当要求保存对新实体中现有实体的引用时,EntityFramework尝试插入null

时间:2012-02-03 15:47:34

标签: asp.net-mvc-3 entity-framework c#-4.0

我正在使用ASP.Net MVC3和实体框架4。

员工有一个OfficeLocation,位于另一个表中以进行规范化。

我有一个新的员工屏幕,下拉办公室位置:

<div class="editor-label">
    @Html.LabelFor(model => model.OfficeLocation.Id, "Office Location")
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.OfficeLocation.Id, new SelectList(ViewBag.OfficeLocations, "Id", "Name"))
    @Html.ValidationMessageFor(model => model.OfficeLocation.Id)
</div>

它指向Id,因为我无法使绑定工作。在我的控制器中,我从数据库加载OfficeLocation,并在保存之前将其存储回我的新Employee中。我此时已经检查过这些值,一切都是正确的。我还尝试过Attach()employee.OfficeLocation,没有任何变化。 employee.OfficeLocation中没有空值,其状态为Unchanged。

employee.OfficeLocation = db.OfficeLocations.Single(d => d.Id == employee.OfficeLocation.Id);
db.Employees.AddObject(employee);
db.SaveChanges();

当我收到有关插入OfficeLocations的例外情况时:

Cannot insert the value NULL into column 'Name', table 'test.HR.OfficeLocations'; column does not allow nulls. INSERT fails.
The statement has been terminated.

我还尝试过通常重启Visual Studio,清理构建等等。

更新:当我允许空值时,我发现它在OfficeLocation中插入了一行并显示了所有空值,然后在Employee表中使用了正确的值。什么。

3 个答案:

答案 0 :(得分:0)

将这两个实体链接在一起时,请勿使用Id。只需在OfficeLocation课程中引入Employee类型的媒体资源,并在创建时将新办公地点与Employee个实例相关联。通过在您的案例中明确指定Id,无需过度复杂。

答案 1 :(得分:0)

当您尝试在视图中使用数据模型时会发生这种情况。您真的应该创建页面特有的自定义视图模型,只需要该页面上所需的数据。

那么,你只需要做这样的事情:

employee.OfficeLocationID = model.OfficeLocationID

您没有设置OfficeLocation.ID,您在员工实体中设置了ID。 OfficeLocation是一个导航属性,可导航到员工的OfficeLocationID属性指定的记录。

答案 2 :(得分:0)

我的问题的根本原因是在处理IModelBinder时,我在框架中导致生成新的OfficeLocations,其中只包含一个(现有的)Id - 在插入时被EF忽略,因为我使用SQL的Id代。我通过让列为空并注意到它在Employee表中正确设置现有Id,同时在另一个表中插入一个新的null-Named记录来解决这个问题。

所以即使新的Entity不再被引用,但是当我保存最初引用它的Employee实体时,框架试图插入它。

希望其他人能从中受益。