简体   繁体   English

实体框架:将多个类映射到一个表

[英]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. 对于多种类型,无法重复使用卫星类DateParamsLocalization 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: 这很难过,因为我能想到的所有其他选择都是丑陋的,或充其量只是笨重的:

  • Create subclasses of DateParams and Localization (and accompanying configurations) for any entity that needs them. 为需要它们的任何实体创建DateParamsLocalization (及其配置)的子类。
  • Just add the properties to all types and work with projections as much as possible (because I assume the whole point of this effort is to reduce the number of properties you're going to query). 只需将属性添加到所有类型并尽可能地使用投影(因为我认为这项工作的重点是减少要查询的属性数)。
  • Use one context hosting the main types without these properties and a second context hosting the satellite types (again, to help querying less properties easily). 使用一个托管没有这些属性的主要类型的上下文和托管卫星类型的第二个上下文(同样,帮助轻松查询较少的属性)。 But unfortunately, you can only join the instances from both contexts in memory, ie LINQ to objects. 但遗憾的是,您只能从内存中的两个上下文中加入实例,即LINQ到对象。
  • Create a third satellite class, combining both smaller classes, and use these three classes as base types. 创建第三个卫星类,将两个较小的类组合在一起,并将这三个类用作基类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架:将多个相似的类映射到相似数据库中的一个表 - Entity Framework: map multiple similar classes to one table in similar databases 实体框架-多个表引用一个表 - Entity Framework - Multiple tables referencing to one table 实体框架| 一个表中的多个对象 - Entity Framework | Multiple Objects from one table 实体框架:如何将具有不同键的多个表映射到一个实体? - Entity Framework: how to map multiple tables with different keys to one entity? 如何在 Entity Framework Core 6.0 中将 map 多个嵌套 class 到一个表 - How to map multiple nested class to one table in Entity Framework Core 6.0 多个类映射到Entity Framework 4.1 Fluent API中的同一表 - Multiple classes mapping to the same table in Entity Framework 4.1 Fluent API 如何将一个属性映射到与实体框架的多个关系? - How can I map one property to multiple relations with entity framework? 具有多个可选一对一关系的实体框架表 - Entity Framework table with multiple optional one to one relationships 如何创建对一个表的多个表引用 - 实体框架 - How to create multiple table references to one table - Entity framework 使用实体框架映射多个PK - Map multiple PK with Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM