我有一个基类
public class BaseClass
{
public int Id {get; set;}
}
和两个派生类
public class Foobar: BaseClass
{
[Required]
public int Whatever {get; set;}
}
public class Snafu: BaseClass
{
[Required]
public int Whatever {get; set;}
}
我正在使用 Table Per Hierarchy 继承并尝试减少重复的列,因此使用 Fluent API,我将它们映射如下:
modelBuilder.Entity<Foobar>().Property(fb => fb.Whatever).HasColumnName("Whatever");
modelBuilder.Entity<Snafu>().Property(sf => sf.Whatever).HasColumnName("Whatever");
然而,这导致
(137,10) :错误 3023:从第 137 行开始映射片段时出现问题:Column BaseClass。必须映射表 BaseClass 中的任何内容:它没有默认值且不可为空。
在 EF6 中,如果我取消这种类型的映射,则似乎可以正常工作[Required]
来自两个子类的属性。添加一个[DefaultValue(0)]
两个派生类的属性并不能解决问题。
知道如何让这些属性共享数据库中的列,同时维护其所需的属性吗?
这实际上是 EF6 中的一个错误。在 EF5 中,该场景根本不起作用(我们会在“列名称必须是唯一的”行中抛出异常)。在 EF6 中,我们做了一些工作来启用它,但显然我们忽略了这样一个事实:即使派生类型中需要该属性,共享列在数据库中也必须为空。后者是因为除非基类是抽象的,否则您需要能够存储基类型的实例,并且对于基类型的任何实例,该列都应该为 null。
我已将该问题提交到我们的错误数据库中:
https://entityframework.codeplex.com/workitem/1924 https://entityframework.codeplex.com/workitem/1924
请随意投票。
至于解决方法,如果无法选择中间类型,则可以将列标记为可为空,并在实体配置上显式附加对 .IsOptional() 的调用。这不会为您提供所需的信息,因为出于 EF 数据验证的目的,对 Fluent API 上的 IsOptional() 的调用将覆盖 [Required] 数据注释。但是,其他风格的数据验证(例如 MVC 的验证)仍将遵循该属性。
还有其他可能的解决方法我还没有尝试过,也许如果可以接受使用 TPT 并且两个派生类型都具有位于不同表中的任何内容,那么这将起作用。我相信任何依赖于设置默认值的方法都无济于事,因为该错误不仅与表架构无法保存基类的实例有关,还与 Code First 生成的 EF 映射不存在有关。有效的。
UPDATE:这将在实体框架版本 6.1.0 中修复,该版本目前处于测试阶段。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)