4

我首先使用 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>.

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

有没有办法做到这一点?

4

1 回答 1

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,您会注意到字段somePropertyToIgoreSET子句中省略了。

于 2014-10-26T21:49:37.700 回答