这是this question的扩展,我现在可以在EF6中使用它。但是,当您拥有具有共享和非共享属性的子类时,似乎存在问题。
让我们说这是我的模型设置:
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
和Licence.LicenceNumber
共享同一列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"));
}
当我生成数据库时,它看起来都按预期工作:
现在问题就在眼前。让我们说Licence
实体也需要记录到期日;所以我按如下方式添加:
public class Licence : Document
{
public string LicenceNumber { get; set; }
public DateTime ExpiryDate { get; set; }
}
现在,当我重新生成数据库时,它看起来像这样:
更重要的是,如果我尝试插入许可证和出生证明,我会得到以下例外:
未处理的类型&#39; System.Data.Entity.Infrastructure.DbUpdateException&#39;发生在EntityFramework.dll
中附加信息:在多个位置生成跨实体或关联共享的值。检查映射是否将EntityKey拆分为多个存储生成的列。
我能理解为什么会引发异常 - 因为数据库没用。
我错过了什么?
答案 0 :(得分:0)
好的,事实证明问题很容易解决,但据我所知,在任何地方都没有记录。所以希望这会帮助有同样问题的人。
看起来,关键是你必须在派生实体上映射每个属性:
modelBuilder.Entity<Document>().Map<Licence>(map =>
{
map.Property(l => l.LicenceNumber).HasColumnName("Number");
map.Property(l => l.ExpiryDate).HasColumnName("ExpiryDate");
});
现在,我的数据库正如我所期望的那样生成,而且一切都与世界相符。
答案 1 :(得分:0)
我不确定你是通过在数据库中将2列放入1来获得更多。我认为你不会节省太多空间而且你无法询问基地Number
的{{1}},即使两个文件都有一个。{1}}。您是否考虑过将Document
字段添加到基础并在覆盖上使用数据注释 - 类似这样的内容?
Number
编辑如果所有文件都没有编号:
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; }
}