我正在使用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表中使用了正确的值。什么。
答案 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实体时,框架试图插入它。
希望其他人能从中受益。