[英]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: 默认约定将此映射到以下列:
I want to have EF4 share the common properties to end up with the following: 我想让EF4共享公共属性,最终得到以下结果:
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. 已定义属性名称“客户”。
One solution to this would be to promote Customer
and Article
properties to the base class: 对此的一个解决方案是将Customer
和Article
属性提升到基类:
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: 这导致了所需的架构:
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.