【发布时间】:2017-04-19 22:43:54
【问题描述】:
我正在处理的实体模型按照以下方式使用继承结构:
public abstract class Line {}
public class WooLine : Line{
public bool wooProperty{ get; set; }
}
public class BooLine : Line
这些都存储在数据库中的表行中。并且在数据库中,wooProperty 列不为空且默认值为 (0)。
这些是在使用 Knockout & Breeze 编写的网络应用程序中维护的。当使用 BooLine 尝试创建新实体时,它会引发一个异常,即我无法将 NULL 插入列 wooProperty。
我设置了一个配置文件来跟踪查询,看起来由于它映射到 Line 表,因此在 Insert EntityFramework 期间读取所有属性并尝试将 NULL 实际插入 wooProperty,因为它不存在于嘘模型。 EF 正在积极尝试将 NULL 插入到我不使用的属性中,我对此感到有些不安......
无论如何。我无法将 wooProperty 移动到 Line 模型 - 它属于 WooLine 模型。我希望通过修改 Breeze 中的元数据或将 wooProperty 强制到 saveChanges 数据上来解决它。但我无法轻而易举地识别元数据中的属性。我试着跑了
metadataStore.registerEntityTypeCtor(
'BooLine', function () {
this.wooProperty = false;
});
这几乎可以工作 - 但 Breeze 将其映射为 __unmapped 值,因此在被 EntityFramework 接收后无法识别。
我还开始尝试重写 EFContextProvider 和重写 BeforeSaveEntity。实体是 BooLine 类型的 ReadOnly,我可以清楚地看到 UnmappedProperties 中的 WooProperty,但我不知道从那里去哪里......有什么想法吗?
某种意义上的 TLDR;想要“欺骗”实体框架,使其在创建实体时认为未映射的值已被映射。
【问题讨论】:
-
IMO 您的问题出在您的数据库中:如果
wooProperty不是通过 TPH 使用Line表的所有实体的一部分,则它不能是NOT NULL。 EF 使用鉴别器列来确定行的实际类型... -
我知道你的意思,但是在通过 WooLine 使用它时确实不能允许它为空,因此允许它为空是没有意义的。在大多数正常情况下,它可以通过默认值来克服。
-
如果你将它标记为
[Required]EF 应该注意它永远不会在null的情况下出现WooLine(并且bool无论如何不能是null).. . -
这取决于我将模型暴露在哪里。虽然 c# 不允许可为空的 bool 值,但如果该列为空,则可能会导致从数据库读取问题。如果 EF 尝试与表交互并且其必填字段中有空值(BooLines 就是这种情况),它将如何表现?修改表并使其可以为空将是绝对的最后手段......
-
...但如果它不是(有效的)
WooLine,EF 将不会读取它。如果您的数据模型有效并且您仅通过 EF 访问数据库,则应该没有问题。如果您还在没有 EF 的情况下访问数据库,则需要注意只创建有效行。也许你也可以切换到 TPT 继承?对于 TPH,EF 使用鉴别器列,并且必须正确设置,以便 EF 区分WooLine和BooLine...
标签: c# asp.net sql-server entity-framework breeze