Поскольку modelBuilder.Entity<BaseModel>()
будет использовать TPH
подход наследования, я предполагаю, что вы не используете подход EF code first для создания базы данных, а используете его для сопоставления ваших моделей с существующей базой данных. Тогда вы можете попробовать что-то вроде этого:
Модели:
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; }
}
DbContext:
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
по ModelType
только в памяти. Также я пытался избежать фильтрации в памяти, используя lazy loading
, но получил некоторое исключение , даже если я только что установил этот пакет без вызова optionsBuilder.UseLazyLoadingProxies()
. Я надеюсь, что это будет исправлено в следующих выпусках.