在我的项目中我有一张桌子Translation
可以有任何模型的翻译。为了实现这一点,该表有两个字段:Model
and ModelId
. The Model
属性保存一个整数,指示模型的类型和ModelId
有这个模型的id。
因此,例如:Product
表有 modeltype id1
。获取具有 id 的产品的所有翻译317
,我搜索翻译Model=1 AND ModelId=317
.
现在我想在 Entity Framework Core 中创建这种关系。我所有的模型都继承自该类BaseModel
拥有财产的ModelType
保存模型类型的 id。该字段未映射,因此在数据库中不可用。
我尝试使用 Fluent api 创建关系,但它不允许我指定更多要过滤的列。
modelBuilder.Entity<BaseModel>()
.HasMany<Translation>(bm => bm.Translations)
// Extra filters
有没有办法创建这种关系,而不必为每个需要翻译的查询手动创建联接?
Since modelBuilder.Entity<BaseModel>()
将使用TPH
继承方法,我假设您没有使用 EF 代码优先方法来创建数据库,而是使用它将模型映射到现有数据库。然后你可以尝试这样的事情:
Models:
public class Translation
{
public int Id { get; set; }
public int Model { get; set; }
public int ModelId { get; set; }
}
public class BaseModel
{
public BaseModel(int modelType)
{
ModelType = modelType;
}
public int Id { get; set; }
public int ModelType { get; set; }
public ICollection<Translation> Translations { get; set; }// only for internal use
public IEnumerable<Translation> ModelTypeTranslations
{
get
{
return this.Translations.Where(t => t.Model == this.ModelType);
}
}
}
public class SomeModel : BaseModel
{
public SomeModel() : base(1) { }
public int SomeProperty { get; set; }
}
public class AnotherModel : BaseModel
{
public AnotherModel() : base(2) { }
public int AnotherProperty { get; set; }
}
数据库上下文:
public class MyDbContext: DbContext
{
...
public DbSet<Translation> Translations { get; set; }
public DbSet<SomeModel> SomeModels { get; set; }
public DbSet<AnotherModel> AnotherModels { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Translation>().HasKey(e => e.Id);
var baseModelTypes = typeof(BaseModel).Assembly.GetExportedTypes()
.Where(t => typeof(BaseModel).IsAssignableFrom(t) && t != typeof(BaseModel)).ToList();
foreach (var type in baseModelTypes)
{
modelBuilder.Entity<Translation>().HasOne(type).WithMany(nameof(BaseModel.Translations)).HasForeignKey(nameof(Translation.ModelId));
modelBuilder.Entity(type).Ignore(nameof(BaseModel.ModelType));
modelBuilder.Entity(type).Ignore(nameof(BaseModel.ModelTypeTranslations));
modelBuilder.Entity(type).HasKey(nameof(BaseModel.Id));
}
}
}
正如你所看到的,你可以使用ModelTypeTranslations
仅获取当前模型类型的翻译。
我应该注意这种方法可能存在性能问题,因为它会过滤Translations
by ModelType
只存在于记忆中。我还尝试通过使用来避免在内存中进行过滤lazy loading https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Proxies/但我得到了一些例外 https://github.com/aspnet/EntityFrameworkCore/issues/11704即使我只是安装了该软件包而不调用optionsBuilder.UseLazyLoadingProxies()
。我希望它能在下一个版本中得到修复。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)