Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 当要求在新实体中保存对现有实体的引用时,EntityFramework试图插入null_Asp.net Mvc 3_Entity Framework_C# 4.0 - Fatal编程技术网

Asp.net mvc 3 当要求在新实体中保存对现有实体的引用时,EntityFramework试图插入null

Asp.net mvc 3 当要求在新实体中保存对现有实体的引用时,EntityFramework试图插入null,asp.net-mvc-3,entity-framework,c#-4.0,Asp.net Mvc 3,Entity Framework,C# 4.0,我正在使用ASP.NETMVC3和EntityFramework4 Employee有一个OfficeLocation,它位于另一个用于规范化的表中 我有一个新的员工屏幕,其中有一个办公室位置下拉列表: <div class="editor-label"> @Html.LabelFor(model => model.OfficeLocation.Id, "Office Location") </div> <div class="editor-field

我正在使用ASP.NETMVC3和EntityFramework4

Employee有一个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>
这时我遇到了一个关于插入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.
我也尝试过重启VisualStudio,清理构建等等


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

将这两个实体链接在一起时,不要使用
Id
。只需在
Employee
类中引入一个
OfficeLocation
类型属性,并在创建新的办公室位置时将其链接到
Employee
实例。在您的案例中,不需要显式指定Id,这样就不会过于复杂。

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

然后,您可以简单地执行以下操作:

employee.OfficeLocationID = model.OfficeLocationID

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

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

因此,即使新实体不再在任何地方被引用,当我保存最初引用它的雇员实体时,框架正在尝试插入它


希望其他人能从中受益。

在这三行之前会发生什么?
employee
是您的操作方法的参数吗?您说状态是
未更改的
,但显然EF创建了一个INSERT语句,这在查看这三行时很难理解。您能否显示完整的操作方法?请您澄清这一行:
employee.OfficeLocation=db.OfficeLocations.Single(d=>d.Id==employee.OfficeLocation.Id)
您想将员工的办公室位置设置为dbContext retrieved值,但要找到该值,您正在传递您试图检索的位置数据?我已经解决了这个问题,但在接下来的六个小时内,我不想回答自己的问题。问题在于,在实体中传递所选id时,MVC或EF(不确定是哪个)正在创建一个空白记录,它认为在插入员工时必须插入该记录,即使该记录未使用。我正在努力使IModelBinder重新工作。我的Employee类中确实有一个OfficeLocation类型的属性。但我需要以某种方式获取该办公地点的Id。您的办公地点和员工实体都是在某个时刻创建的。您可以将它们相互链接在一起,而无需引用特定的Id。Id是EF在本例中在内部使用的东西,您永远不需要为它操心。如果需要id,请致电employee.OfficeLocation.id。但是我发现你的问题是,你想要得到这个Id来填充一个空的OfficeLocation。这行不通。想想看。非办公地点的Id不会从某处神奇地出现。您至少需要显式设置一次。我不确定您是否在跟踪我。我从表单数据中获取id,然后使用页面上的选择按id加载相应的OfficeLocation。好的,我现在明白你的意思了。是的。他不是在
下拉列表中为
设置了
OfficeLocation.Id
?我同意外键属性会让事情变得更简单,但他根本没有说他在
Employee
类中有一个FK属性。我仍然看不出问题中的代码有什么问题。@Slauma-他必须在employee中有一个外键字段,否则导航属性将不起作用。导航属性使用FK属性来运行。您不设置OfficeLocation.Id,因为这仅在插入新记录或更新当前记录时完成。它不用于分配ID。不,两个点都是错误的。您可以使用不带FK属性的工作导航属性,当然也可以设置Id,否则无法将现有实体附加到上下文。
employee.OfficeLocationID = model.OfficeLocationID