使用EF 6 Database First时,已设默认值的非空列插入报错“Cannot Insert NULL”
我之前也遇到过一模一样的问题!当用EF6的Database First时,数据库里明明给非空字段设了默认值,但插入新记录时还是报Cannot insert the value NULL into column...的错误,本质是EF没识别到数据库的默认值规则,或者在插入时硬传了NULL值。下面给你几个靠谱的解决办法:
1. 先确认数据库的默认值约束是否生效
首先得排除最基础的问题:打开SQL Server管理器,检查你的Auth.AppAttributes表中attr_is_required字段的默认值约束是否真的存在。可以执行这个SQL验证:
SELECT name, definition FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('Auth.AppAttributes') AND parent_column_id = (SELECT column_id FROM sys.columns WHERE object_id = OBJECT_ID('Auth.AppAttributes') AND name = 'attr_is_required')
如果查不到结果,说明建表时的默认值没加上,得先给字段补上DEFAULT约束,比如:
ALTER TABLE Auth.AppAttributes ADD CONSTRAINT DF_AppAttributes_attr_is_required DEFAULT (0) FOR attr_is_required;
2. 修改EDMX模型,让EF自动应用默认值
如果数据库默认值没问题,那就是EF的模型没同步这个设置。操作步骤:
- 打开你的EDMX文件,找到
AppAttributes实体对应的attr_is_required属性。 - 右键这个属性,选择Properties(属性窗口)。
- 在属性窗口里找到Default Value,输入你的默认值(比如bit类型填
False或0,字符串类型填对应的默认内容)。 - 保存EDMX,重新生成实体类。
这样以后你new一个AppAttributes对象时,这个属性会自动带上默认值,EF插入时就不会传NULL了。
3. 让EF插入时忽略该字段,由数据库处理默认值
如果你的字段是那种只能由数据库生成默认值,后续也不需要手动修改的情况,可以设置StoreGeneratedPattern:
- 同样在EDMX的属性窗口里,找到StoreGeneratedPattern,设置为
Computed。 - 保存并重新生成实体类。
这时候EF会认为这个字段的值是数据库计算/生成的,插入新记录时不会把这个字段包含在INSERT语句里,数据库就会自动应用默认值了。不过要注意,设置成Computed后,你后续手动修改这个属性的值,EF也不会同步到数据库,所以只适合不需要手动修改的字段。
4. 用部分类添加默认值(避免EDMX覆盖)
如果你经常需要更新EDMX模型,上面的修改可能会被重新生成覆盖,这时候可以用部分类来设置默认值:
- 在项目里创建一个和自动生成的实体类同名的部分类,比如:
namespace YourProjectNamespace.Models // 要和自动生成的实体类命名空间一致 { public partial class AppAttributes { public AppAttributes() { attr_is_required = false; // 这里设置你的默认值 } } }
这样每次EDMX重新生成时,这个部分类不会被覆盖,实体对象创建时都会自动带上默认值。
内容的提问来源于stack exchange,提问作者Gary O. Stenstrom

