不可为空的数字字段

问题描述:

实体框架定义约束这是一个跟进这个问题
Entity Framework 4 not respecting database constraints for numeric fields不可为空的数字字段

是否有可能实现以下

表:富
PKID - INT,主,自动增量
Bar-int,允许null = false,无默认值

现在,当从生成EF模型时数据库中'Bar'字段为 正确定义为Nullable = false,Type = Int32。

现在,当我做以下操作时

var foo = new Foo();
context.AddToFoos(foo);
context.SaveChanges();

该行插入到数据库中,'Bar'的值为0?

我期望的是应用程序级别的异常,因为Bar在技术上还没有被应用程序设置。其.Net默认值不会自动转换为特定数据库的有效值。

该行为应该与数据库中的字符串列类似。字符串被正确处理,因为它们有一个空状态,这很好地转换。

这对于数字列通常如何实现?

当您不想存储0时,请不要忘记在模型对象中设置Bar属性的值。创建新对象并调用SaveChanges时,将向数据库发送INSERT命令,该数据库包含值为全部您的模型属性被映射到数据库表。一个类中的int属性始终有一个值,并且您已将此值设置为0 - 即通过调用该对象的构造函数。

EF不会仅将对象的一半发送到数据库,这是Object-Relational-Mapper的基本要点。当然,通过提交原始SQL INSERT命令,您可以只设置表行的列值的一半,并且如果您没有为Bar列设置值,则会发生异常。但是当你使用ORM时,你不提交INSERT命令,但是你存储了新的对象。

究竟是什么问题?如果没有Bar的值是有效的,则该列应该是可空的,并且该属性为int?。如果它必须有一个值,但不是值0,那么它是在对象的构造函数中将Bar设置为1或某物的问题,或者在保存对象之前应用适当的验证。

你想拥有的那种例外的是不可能的,是没有意义的,我的意见,因为这是不可能的设置在INSERT命令EF值将存储对象

+0

感谢时提交,请务必设置代码中的值很好,但那不是问题。想象一下有20多个不同应用程序将数据写入数据库的场景。数据库约束表示“您必须为此列提供有效值”。由于我不能保证每个应用程序都正确实现,所以ORM尊重这个约束是很好的。这种功能已经存在了20多年。如果该字段不是脏的,不要将其写入数据库或抛出。不要从框架写入任何默认值到数据库。 – bic 2011-05-24 15:03:54

+0

@bic:约束条件是尊重的,因为* new *对象的所有属性都是脏的,并且只有更新的列才会在更新命令中发送到数据库。约束检查的类型只是必需的,因为在关系数据库中,您可以在创建新行时设置单个列。在一个ORM(以及OO数据库)中你不能,因此约束检查是不必要的。也许这是一个“对象 - 关系阻抗不匹配”的例子:在“O”端不存在默认值的简单数据类型,例如“R”端没有默认值的列。 – Slauma 2011-05-24 15:33:02

+0

@bic:另一点:考虑你使用POCO。一个对象是在上下文之外创建的“某处”,例如在另一个程序集中创建的,或者它来自任何远程服务,另一方面的开发人员将“Bar”明确设置为0,因为它是他想存储的有效值。 EF如何识别这是否是在对象构造函数中创建的“默认值”,或者是否已在代码中明确设置?我想不出来。这种检测,如果值已被明确设定是不可能的,至少在POCO中是这样。 – Slauma 2011-05-24 15:45:27