C# 实体框架:将多个类映射到一个表
我认为这在nhiberate中是可能的,但我的问题是关于实体框架 在我的数据库模型中(我不能修改),我有多余的列,我想存储在不同的类中 例如:C# 实体框架:将多个类映射到一个表,c#,entity-framework,C#,Entity Framework,我认为这在nhiberate中是可能的,但我的问题是关于实体框架 在我的数据库模型中(我不能修改),我有多余的列,我想存储在不同的类中 例如: public class DateParams { public DateTime CreationDate { get; set; } public DateTime ModificationDate { get; set; } // some methods } public class Localization {
public class DateParams
{
public DateTime CreationDate { get; set; }
public DateTime ModificationDate { get; set; }
// some methods
}
public class Localization
{
public String EnglishLabel { get; set; }
public String FrenchLabel { get; set; }
// some methods
}
然后我会在我的一些模型中使用它们:
public class Account // Localization && DateParams
{
public int ID { get; set; }
public String Name { get; set; }
public Localization Localization { get; set; }
public DateParams DateParams { get; set; }
}
public class Lead // DateParams only
{
public int ID { get; set; }
public String Name { get; set; }
public DateParams DateParams { get; set; }
}
我想要达到的是拥有这样的东西
public class LocalizationMap : EntityTypeConfiguration<Localization>
{
public LocalizationMap()
{
Property(e => e.EnglishLabel).HasColumnName("en");
Property(e => e.FrenchLabel).HasColumnName("fr");
}
}
public class AccountMap : EntityTypeConfiguration<Account>
{
public AccountMap()
{
HasKey(x => x.ID);
Property(e => e.Name).HasColumnName("Name");
HasSubMapping(new LocalizationMap());
HasSubMapping(new DateParamsMap());
ToTable("Account");
}
}
公共类本地化映射:EntityTypeConfiguration
{
公共本地化地图()
{
属性(e=>e.EnglishLabel);
属性(e=>e.FrenchLabel);
}
}
公共类AccountMap:EntityTypeConfiguration
{
公共帐户映射()
{
HasKey(x=>x.ID);
属性(e=>e.Name);
HasSubMapping(新本地化映射());
HasSubMapping(新的DateParamsMap());
总额(“账户”);
}
}
我可以用继承来解决这个问题,但C#不允许多重继承。我不会让你高兴的 有一种称为表拆分的EF功能。顾名思义,这允许我们将一个数据库表映射(拆分)到概念模型中的多个类。在您的情况下,
帐户
的映射如下所示:
class AccountMap : EntityTypeConfiguration<Account>
{
public AccountMap()
{
ToTable("Account");
HasKey(x => x.ID);
HasRequired(a => a.DateParams).WithRequiredPrincipal();
HasRequired(a => a.Localization).WithRequiredPrincipal();
}
}
class DateParamsMap : EntityTypeConfiguration<DateParams>
{
public DateParamsMap()
{
ToTable("Account");
}
}
class LocalizationMap : EntityTypeConfiguration<Localization>
{
public LocalizationMap()
{
ToTable("Account");
}
}
class AccountMap:EntityTypeConfiguration
{
公共帐户映射()
{
总额(“账户”);
HasKey(x=>x.ID);
HasRequired(a=>a.DateParams)。WithRequiredPrincipal();
HasRequired(a=>a.Localization)。WithRequiredPrincipal();
}
}
类DateParamsMap:EntityTypeConfiguration
{
公共日期参数映射()
{
总额(“账户”);
}
}
类本地化映射:EntityTypeConfiguration
{
公共本地化地图()
{
总额(“账户”);
}
}
但这立即显示了问题:类型配置中的表名“Account”是硬编码的。无法对多种类型重用附属类DateParams
和Localization
。而且,在您尝试之前,EF不会接受像DateParams
这样的泛型
这是可悲的,因为我能想到的所有其他选择都是丑陋的,或者说是笨拙的:
- 为任何需要的实体创建
和DateParams
(以及附带的配置)的子类Localization
- 只需将属性添加到所有类型中,并尽可能多地使用投影(因为我假设这项工作的全部目的是减少要查询的属性数量)
- 使用一个上下文托管主类型而不包含这些属性,使用另一个上下文托管附属类型(同样,帮助轻松查询较少的属性)。但不幸的是,您只能将内存中两个上下文中的实例连接起来,即LINQ到对象
- 创建第三个附属类,合并两个较小的类,并将这三个类用作基本类型
complextypeName\u propertyName
的表列,但可以通过在DbContext
中覆盖OnModelCreating(DbModelBuilder modelBuilder)
来更改此行为,如中所述
例如:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<Localization>();
modelBuilder.Entity<Account>().Property(x => x.Localization.EnglishLabel).HasColumnName("en");
modelBuilder.Entity<Account>().Property(x => x.Localization.FrenchLabel).HasColumnName("fr");
// et cetera
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType();
modelBuilder.Entity().Property(x=>x.Localization.EnglishLabel).HasColumnName(“en”);
modelBuilder.Entity().Property(x=>x.Localization.FrenchLabel).HasColumnName(“fr”);
//等等
}
也许您应该看看实体框架复杂类型,例如:@ChrifP,可以将您的评论作为asnwser发布,以便我可以接受吗?我选择了complextype解决方案。