【问题标题】:How can I replace an entity by another entity with the same key in an Entity Framework DB first approach?如何在 Entity Framework DB first 方法中用具有相同键的另一个实体替换一个实体?
【发布时间】:2013-03-28 01:56:30
【问题描述】:

我首先使用 EF 5 数据库编写 MVC 4 Web 应用程序。我有一些明显微不足道的问题,我找不到合适的解决方案。这些问题与对象状态管理器有关。

在最简单的场景中,一切正常:我使用 Find 从数据库中读取实体,将它们放入视图中,等待响应,重构实体,使用 Attach、EntityState.Modified 和 SaveChanges 将其写回。如果在处理请求时,我再次从数据库中获取实体,则会出现问题。

如果出现以下情况,我会这样做:
1. 由于某种原因,我想检查原始实体的一些值。
2. 我的一些值不能被修改,因为它们标识了实体。我将这些放在我的视图中仅供参考,使用 DisplayFor。当然,重构模型没有这些值。我从数据库中获取原始实体,并在控制器中使用 TryUpdateModel 将其与视图中的模型合并。

调用 Attach 时出现异常“ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。”。

如果我使用Context.Entry(t).CurrentValues.SetValues(t); 而不是DbSet.Attach(t);,我会得到以下异常:

Member 'CurrentValues' cannot be called for the entity of type 'Price' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet<Price>.

据我了解,具有特定键的实体有两个实例。我想做一个我想保存的,替换现在的一个,如果有的话。我希望这是自动的,也就是说,我不必告诉是否已经存在另一个必须更换的。

有没有办法做到这一点?

【问题讨论】:

标签: entity-framework modelstate


【解决方案1】:

与此同时,我已经开始使用模型优先方法,所以我不太确定以下内容是否适用,但我认为其中一些可能有用。

  1. 使用someContext.someDbSet.AsNoTracking() 运行查询,如果 您只是想查找一些数据,但不打算更新 有变化的数据库。请参阅 MSDN 上的 AsNoTracking
  2. 不更新某些模型属性。这将帮助您更新,例如用户配置文件,未更新散列密码,存储在同一模型中。

    someContext.someDbSet.Attach(someModelInstance);
    var entry = substanceContext.Entry(someModelInstance);
    entry.State = EntityState.Modified;
    entry.Property("somePropertyToIgnore").IsModified = false;
    substanceContext.SaveChanges();
    

如果您查看第二个解决方案中生成的 SQL,您会注意到 somePropertyToIgore 字段从 SET 子句中省略了.

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多