我首先使用EF 5数据库编写MVC 4 Web应用程序。我有一些显然是微不足道的问题,我找不到合适的解决方案。这些问题与对象状态管理器有关。
在最简单的场景中,一切正常:我使用Find从数据库中读取实体,将它们放在视图中,等待响应,重构实体,使用Attach,EntityState.Modified和SaveChanges将其写回。如果在处理请求时,我再次从数据库中获取实体,则会出现问题。
如果出现以下情况,我会这样做:
我想出于某种原因检查原始实体的某些值
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>.
据我了解,有两个具有特定密钥的实体实例。我想制作一个我要保存的那个,取而代之的是,如果有的话。我希望这是自动的,也就是说,我不必告诉是否已经存在另一个必须被替换的人。
有没有办法实现这个目标?
答案 0 :(得分:1)
与此同时,我开始使用模型优先方法,所以我不确定以下是否适用,但我认为其中一些可能有用。
someContext.someDbSet.AsNoTracking()
运行查询,如果
你只是想查找一些数据,但不打算更新
数据库有变化。请参阅MSDN上的AsNoTracking。从更新中排除某些模型属性。这有助于您更新,例如用户配置文件,不更新散列密码,存储在同一模型中。
someContext.someDbSet.Attach(someModelInstance);
var entry = substanceContext.Entry(someModelInstance);
entry.State = EntityState.Modified;
entry.Property("somePropertyToIgnore").IsModified = false;
substanceContext.SaveChanges();
如果查看第二个解决方案中生成的 SQL ,您会注意到 SET 子句中遗漏了 somePropertyToIgore 字段