简体   繁体   English

如何在每个层次结构(TPH)映射中共享公用列名称

[英]How to share common column names in a Table per Hierarchy (TPH) mapping

I'm using Entity Framework 4 CTP5 code first approach and I have a Table per Hierarchy (TPH) mapping. 我正在使用Entity Framework 4 CTP5代码第一种方法,我有一个每层次表(TPH)映射。 Some of my classes in the hierarchy have properties in common. 层次结构中的某些类具有共同的属性。

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class C : BaseType
{
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

The default convention maps this to the following columns: 默认约定将此映射到以下列:

  • Id ID
  • Article1 第1条
  • Article2 第二条
  • Customer1 customer1表
  • Customer2 顾客2
  • Manufacturer 生产厂家
  • Order 订购
  • Type 类型

I want to have EF4 share the common properties to end up with the following: 我想让EF4共享公共属性,最终得到以下结果:

  • Id ID
  • Article 文章
  • Customer 顾客
  • Manufacturer 生产厂家
  • Order 订购
  • Type 类型

Apart from the reduced number of columns, this has the advantage of being able to search for records based on Article for example, without having to know which types exactly have an Article property. 除了减少列数之外,这还具有能够基于文章搜索记录的优点,而无需知道哪些类型具有Article属性。

I tried mapping each common property to the same column: 我尝试将每个公共属性映射到同一列:

modelBuilder.Entity<B>().Property(n => n.Article).HasColumnName("Article");
modelBuilder.Entity<C>().Property(n => n.Article).HasColumnName("Article");

but this threw the following exception: 但是这引起了以下异常:

Schema specified is not valid. 指定的架构无效。 Errors: (36,6) : error 0019: Each property name in a type must be unique. 错误:(36,6):错误0019:类型中的每个属性名称必须是唯一的。 Property name 'Article' was already defined. 已定义属性名称“文章”。

Does anyone know how to get around this validation rule? 有谁知道如何绕过这个验证规则?

There is no workaround to bypass this validation. 没有解决方法可以绕过此验证。 In TPH a column is either belongs to the base class which is inherited by all childs or is specialized to the child class. 在TPH中,列要么属于所有子级继承的基类,要么专用于子类。 You cannot instruct EF to map it to two of your childs but not for the other. 您无法指示EF将其映射到您的两个孩子,而不是另一个孩子。 Attempting to do so (for example by putting [Column(Name = "Customer")] on both A.Customer and B.Customer) will be causing a MetadataException with this message: 尝试这样做(例如通过在A.Customer和B.Customer上放置[Column(Name = "Customer")]将导致带有以下消息的MetadataException

Schema specified is not valid. 指定的架构无效。 Errors: (10,6) : error 0019: Each property name in a type must be unique. 错误:(10,6):错误0019:类型中的每个属性名称必须是唯一的。 Property name 'Customer' was already defined. 已定义属性名称“客户”。


TPH Solution: TPH解决方案:

One solution to this would be to promote Customer and Article properties to the base class: 对此的一个解决方案是将CustomerArticle属性提升到基类:

public class BaseType {
    public int Id { get; set; }
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class A : BaseType {
    public string Order { get; set; }
}

public class B : BaseType { }

public class C : BaseType {
    public string Manufacturer { get; set; }
}

Which results to the desired schema: 这导致了所需的架构:

替代文字


TPT Solution (Recommended): TPT解决方案(推荐):

That said, I recommend to consider using Table per Type (TPT) since it's a better fit for your scenario: 也就是说,我建议考虑使用每种类型的表 (TPT),因为它更适合您的场景:

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }

    [Column(Name = "Article")]
    public string Article { get; set; }
}

public class C : BaseType
{
    [Column(Name="Article")]
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<BaseType> BaseTypes { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BaseType>().ToTable("BaseType");
        modelBuilder.Entity<A>().ToTable("A");
        modelBuilder.Entity<C>().ToTable("C");
        modelBuilder.Entity<B>().ToTable("B");          
    }
}

替代文字

对于任何遇到此问题的人,现在已经在EF6: Entity framework - Codeplex中修复了它

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

相关问题 层次结构中多类的 Fluent NHibernate table-per-inheritance (TPH) 映射 - Fluent NHibernate table-per-inheritance (TPH) mapping for multi class in the hierarchy 共享列名的每个层次结构的代码第一表错误 - Code First Table Per Hierarchy error with shared column names 派生属性到特定表特定列的EF6 TPH映射 - EF6 TPH mapping of derived property to specific table specific column 每个层次结构映射问题的流畅的NHibernate表 - Fluent NHibernate table per hierarchy mapping problem 每个层次结构映射的代码优先表 - Code First table per hierarchy mapping 实体框架数据库首先 - 每个层次表(TPH)递归关系实现 - Entity framework database first - Table per hierarchy (TPH) recursive relationship implementation 如何更改映射表的列名? - How to change the column names of a mapping table? 具有共享列和未共享列的每个层次结构表映射 - Table per Hierarchy table mapping with both shared and unshared columns 具有TPH鉴别符列的表上的简单成员资格 - Simple Membership on table with TPH discriminator column 每个子类策略的表中列名错误,层次结构中有抽象类 - Wrong column name in table per subclass strategy with abstract class in hierarchy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM