【发布时间】:2011-11-12 03:40:38
【问题描述】:
我在我的 ASP.NET MVC 2 Web 应用程序中使用 EF4。我正在尝试将数据保存到数据库。将新数据添加到数据库是相当简单的。我正在这样做:
PeopleEntities entities = ObjectContextFactory.GetPeopleEntities();
entities.People.AddObject(person); // The Person object created from user input.
entities.SaveChanges();
但是,这有一个不幸的副作用,就是总是将新对象保存到我的数据库中。我确实需要这个功能(当然),但我还想要更新数据库中现有项目的选项(或者,如果数据库中尚不存在该项目,则另存为新项目)。
我尝试将上面的第二行替换为以下内容:
entities.People.ApplyCurrentValues(person);
但我收到了这个 InvalidOperationException:
具有匹配键的对象 提供的对象的键不能 可以在 ObjectStateManager 中找到。 验证的键值 提供的对象匹配键值 必须更改的对象的 已申请。
无论我尝试添加新人员还是尝试编辑人员,都会发生这种情况。我可以做些什么来纠正这个问题?
问题更新:
我尝试了下面提供的答案,但是当我去调试 Single 语句时,我发现我保存的人的 ID 始终为 0 - 即使我已经从数据库中检索了它。所以,我想首先发布我正在做什么来检索 Web 应用程序。也许这会有所帮助。
当我导航到显示人员信息的页面时,地址是:
http://localhost/Person/Index/1
其中 1 是数据库中 Person 的 ID。我通过包含以下行的存储库方法检索 Person (实体是存储库类的成员变量):
public Person GetPerson(int id)
{
return entities.People.FirstOrDefault(p => p.PersonID == id);
}
这个方法是从我项目的控制器中调用的。看起来像这样:
public ActionResult Index(int id)
{
var entities = ObjectContextFactory.GetScenarioDBEntities();
Person person = new PersonRepository(entities).GetPerson(id);
return View("Index", person);
}
现在我看到了,我想知道每次我想检索一个新的人时实例化一个本地实体对象是否是错误的。 (现在要去研究。)无论如何,当我这样做时,最终去保存之前的Person,我发现PersonID值总是== 0。
【问题讨论】:
-
这很奇怪 - 所以你是说如果数据库中有一个 ID = 10 的人,那么你尝试检索那个 ID 为 0 的人?这没有任何意义。认为您需要重新设计实体/上下文设计。您不应该为每个操作方法更新一个新的上下文。您应该为每个 HTTP 请求实例化一个,并通过控制器的 ctor 传递它(最好使用 DI 容器)
-
@RPM1984 - 这就是我感到困惑的原因。这就是我以为我在做的事情。如果您阅读下面的@Neil Fenwick 的建议(他发送的链接),我就是这样做的。 (我为我自己解决了这一点而感到自豪。)我认为我的问题可能在于我如何在提交时将信息发送回去。这是我一直有点模糊的。目前我正在使用 MVC2 强类型部分页面。看起来我基本上只需要一个 Controller 方法来接收 POST 上的数据,我会按照上面的方法写出来。好像没那么容易……
-
@RPM1984 - 据我所知,ID 始终为 0 的原因是因为我在编辑页面上没有为 ID 使用隐藏字段。但是,当我将它添加到页面时,我的解决方案仍然不起作用。我不觉得我在实现这个方面有什么问题......但我似乎无法让它发挥作用。
标签: database asp.net-mvc-2 entity-framework-4