C# 具有共享列和非共享列的每个层次结构的表映射
这是一个扩展,据我所知,它现在在EF6中工作。然而,当您拥有同时具有共享和非共享属性的子类时,似乎会出现问题 假设这是我的模型设置:C# 具有共享列和非共享列的每个层次结构的表映射,c#,sql-server,entity-framework,entity-framework-6,table-per-hierarchy,C#,Sql Server,Entity Framework,Entity Framework 6,Table Per Hierarchy,这是一个扩展,据我所知,它现在在EF6中工作。然而,当您拥有同时具有共享和非共享属性的子类时,似乎会出现问题 假设这是我的模型设置: public abstract class Document { public int Id { get; set; } public string NameOnDocument { get; set; } } public class BirthCertificate : Document { public string Registr
public abstract class Document
{
public int Id { get; set; }
public string NameOnDocument { get; set; }
}
public class BirthCertificate : Document
{
public string RegistrationNumber { get; set; }
}
public class Licence : Document
{
public string LicenceNumber { get; set; }
}
在数据库中,我希望BirthCertificate.RegistrationNumber和license.licenseNumber共享同一列Number。因此,我将我的模型设置为:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Document - base class
modelBuilder.Entity<Document>().HasKey(d => d.Id);
modelBuilder.Entity<Document>()
.Property(d => d.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Document>()
.Property(d => d.NameOnDocument)
.HasColumnName("Name");
// Birth certificate
modelBuilder.Entity<Document>().Map<BirthCertificate>(map =>
map.Property(c => c.RegistrationNumber).HasColumnName("Number"));
// Licence
modelBuilder.Entity<Document>().Map<Licence>(map =>
map.Property(l => l.LicenceNumber).HasColumnName("Number"));
}
现在,当我重新生成数据库时,它如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Document - base class
modelBuilder.Entity<Document>().HasKey(d => d.Id);
modelBuilder.Entity<Document>()
.Property(d => d.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Document>()
.Property(d => d.NameOnDocument)
.HasColumnName("Name");
// Birth certificate
modelBuilder.Entity<Document>().Map<BirthCertificate>(map =>
map.Property(c => c.RegistrationNumber).HasColumnName("Number"));
// Licence
modelBuilder.Entity<Document>().Map<Licence>(map =>
map.Property(l => l.LicenceNumber).HasColumnName("Number"));
}
此外,如果我尝试插入许可证和出生证明,我会得到以下例外情况:
EntityFramework.dll中发生类型为“System.Data.Entity.Infrastructure.DbUpdateException”的未处理异常
附加信息:在多个位置生成跨实体或关联共享的值。检查映射是否未将EntityKey拆分为多个存储生成的列
我可以理解为什么会出现这种异常——因为数据库是无用的
我错过了什么?好的,所以问题很容易解决,但据我所知,没有任何地方记录在案。所以希望这能帮助有同样问题的人 看起来,关键在于必须映射派生实体上的每个属性:
现在,我的数据库按照我的预期生成,世界上一切正常。我不确定在数据库中将2列放进1列会获得多少收益。我认为这样做不会节省太多空间,也无法查询基本文档的编号,即使两个文档都有一个。您是否考虑过将数字字段添加到基础中,并在覆盖上使用数据注释-类似这样的内容
public abstract class Document
{
public int Id { get; set; }
public string NameOnDocument { get; set; }
public virtual string Number
}
public class BirthCertificate : Document
{
[Display(Name="Registration Number"]
[Required]
public override string Number { get; set; }
}
public class Licence : Document
{
[Display(Name="Licence Number"]
[Required]
public override string Number { get; set; }
}
编辑,如果所有文档未编号:
public abstract class Document
{
public int Id { get; set; }
public string NameOnDocument { get; set; }
}
public abstract class NumberedDocument : Document
{
public virtual string Number
}
public class BirthCertificate : NumberedDocument
{
[Display(Name="Registration Number"]
[Required]
public override string Number { get; set; }
}
这是一个更大问题的简单例子。。。实际上,大约有6种文档类型,每种文档类型共享大约5个公共属性和一些半公共属性。并非所有文档都有编号。谢谢你的建议。@gerrod编辑以展示如何对半公共属性使用继承;但这仍然太简单了:-。它更像是——连同公共属性,我的表有七个可能的共享属性——PropertyA、PropertyB。。。。财产。Document1有PropertyA,PropertyC。文档2有PropertyC、PropertyE、PropertyF。文档3有PropertyB、PropertyE、PropertyG。etc有六种不同的文档类型,每种类型具有不同的共享属性组合。
public abstract class Document
{
public int Id { get; set; }
public string NameOnDocument { get; set; }
}
public abstract class NumberedDocument : Document
{
public virtual string Number
}
public class BirthCertificate : NumberedDocument
{
[Display(Name="Registration Number"]
[Required]
public override string Number { get; set; }
}