【问题标题】:How to perform an update using ObjectContext如何使用 ObjectContext 执行更新
【发布时间】: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


【解决方案1】:

entities.SaveChanges(); 是您所需要的,只要您从相同的确切上下文中检索对象。否则,您需要致电entities.Attach(person);

这应该可行:

PeopleEntities entities = ObjectContextFactory.GetPeopleEntities();
var person  = entities.People.Single(p => p.Id == id); // or some other way to get the person in question
// make changes to person ...
entities.SaveChanges();

【讨论】:

  • 发生了一些奇怪的事情。我按照你说的去做,但我发现我保存的 Person 的 ID 始终为 0 - 即使我正在从数据库中检索 Person。什么会导致这种情况发生? (我已经更新了我的问题以显示我在做什么。)
  • 我会接受这个答案,因为我知道这是正确的答案。我相信来源中存在不同的问题。谢谢。
  • 尝试以 XML 格式打开您的 edmx 文件(通过右键单击并选择“打开方式...”),然后扫描文件以查找 cmets。有时,数据模型的问题只会在 XML 中显示为 cmets。
【解决方案2】:

试试这个:

public void UpdateEntity(Entity entity) {
   var entityKeyObj = DataContext.Entity.Where(i => i.ID == entity.ID).First();
   entity.EntityKey = entityKeyObj.EntityKey;
   DataContext.ApplyCurrentValues("Units",entity);
   SaveChanges();
}

【讨论】:

    【解决方案3】:
    var entity = context.Table.Single(predicate);
    entity.Field = "stuff";
    context.SaveChanges();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多