2

具有数据库生成字段的实体框架6在插入时失败。从我读过的标记为DatabaseGenerated的列开始,EF不会尝试在该字段中插入/更新任何内容,这对我来说尤其重要,因为数据库上的字段是SQL Server计算列,而不仅仅是默认值值,这是我在堆栈溢出/谷歌很多类似的问题中看到的。实体框架6 w/DatabaseGeneratedOption.Computed:列不允许空值。 INSERT失败

列定义(在计算列使用用户定义的函数):

ALTER TABLE dbo.MyModel ADD [TotalUnits] AS ([dbo].[CalculateTotalUnits]([Id])); 

EF定义:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
public decimal TotalUnits { get; private set; } 

然后,我只是在做一个

var myNewModel = new MyModel(); 
DbContext.MyModels.Add(myNewModel); 
DbContext.SaveChanges(); 

其中给出:

System.Data.SqlClient.SqlException:无法将值NULL插入到'TotalUnits'列中,表'MyDatabase.dbo.MyModel';列不允许有空值。 INSERT失败。

为什么EF试图在计算列中插入NULL值,我该如何告诉它不要?

+0

你确定数据库模式配置正确吗? EF会将NULL插入到计算列和标识列中,因为这些列预计由DBMS设置。 – DevilSuichiro

+0

@DevilSuichiro如果预计由DBMS设置,为什么EF会尝试将_anything_(甚至是NULL)插入到它中?在SSMS中,如果我运行INSERT INTO MyModel([...],[TotalUnits])VALUES([...],NULL)'我得到了预期的'列'TotalUnits'不能修改,因为它是一个计算列或是UNION运算符的结果.'。你不能在计算列中插入任何东西,甚至是'NULL'。我不知道为什么实体框架会尝试... – Seafish

+1

这是相同的架构?就像你在那里看到的那样,给定的异常是抛出的SqlException,并且它有所不同。什么是计算的SQL语句? – DevilSuichiro

回答

1

运行集成测试时显示EF配置为使用自动迁移而不是我们自己的迁移。由于计算列在迁移的Up方法期间被添加到自定义SQL脚本中,所以在测试期间列实际上不是computed列,但实际上由EF生成为常规decimal(不可为空)字段。因此,试图向上下文添加新模型导致EF将NULL插入到这些列中并炸毁。

解决方案是在集成测试中实际运行迁移。一旦实际计算出列,EF就会停止跟踪它。

相关问题