[英]Entity Framework : map multiple classes to one table
I think this is possible in nhiberate, but my question is about Entity Framework. 我认为这在nhiberate中是可能的,但我的问题是关于实体框架。
In my database model - which I cannot modify - I have redundant columns that I would like to store in different classes. 在我的数据库模型中 - 我无法修改 - 我有冗余列,我想存储在不同的类中。
Example : 示例:
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
}
And then I would use them in some of my models : 然后我会在我的一些模型中使用它们:
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; }
}
What I would like to achieve is having something like this 我想要实现的是拥有这样的东西
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");
}
}
I could use inheritance to solve this, but C# does not allow multiple inheritance. 我可以使用继承来解决这个问题,但C#不允许多重继承。
You can achieve this by using complex types. 您可以通过使用复杂类型来实现此目的。 These map to table columns named like
complextypeName_propertyName
but this behaviour can be changed by overwriting OnModelCreating(DbModelBuilder modelBuilder)
in DbContext
like described in Entity Framework - Reuse Complex Type 这些地图命名为喜欢的表列
complextypeName_propertyName
但这种行为可以通过覆盖被改变OnModelCreating(DbModelBuilder modelBuilder)
中DbContext
就像在描述实体框架-重用复杂类型
For your example: 对于你的例子:
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
}
I'm not going to make you happy. 我不会让你开心的。
There is an EF feature called Table Splitting . 有一个名为Table Splitting的EF功能。 As the name suggests, this allows us to map (split) one database table to multiple classes in the conceptual model.
顾名思义,这允许我们将一个数据库表映射(拆分)到概念模型中的多个类。 In your case, the mappings for
Account
would look like this: 在您的情况下,
Account
的映射将如下所示:
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");
}
}
But this immediately shows the problem: the table name "Account" in the type configurations is hard coded. 但是这立即显示了问题:类型配置中的表名“Account”是硬编码的。 There's no way to reuse the satellite classes
DateParams
and Localization
for multiple types. 对于多种类型,无法重复使用卫星类
DateParams
和Localization
。 And, before you try, EF won't accept generics like DateParams<T>
. 并且,在您尝试之前,EF不会接受像
DateParams<T>
这样的泛型。
Which is sad, because all other options I can think of are ugly, or clunky at best: 这很难过,因为我能想到的所有其他选择都是丑陋的,或充其量只是笨重的:
DateParams
and Localization
(and accompanying configurations) for any entity that needs them. DateParams
和Localization
(及其配置)的子类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.