【问题标题】:Attaching an entity of type.. failed because附加类型的实体.. 失败,因为
【发布时间】:2017-03-29 16:10:55
【问题描述】:

我在我的一个控制器上执行编辑操作时遇到了奇怪的行为。

这是我的代码:

public ActionResult Edit([Bind(Include = "ID,FirstName,LastName,Email,deleted,AId")] Information personInformation)
{

    // to stop multiple calls to database
    var lstOfPeople = db.Information.Where(x => x.deleted == false).ToList();

    if (ModelState.IsValid)
    {

        if (lstOfPeople.Any(x => x.Email.Equals(personInformation.Email, StringComparison.CurrentCultureIgnoreCase) && x.ID != personInformation.ID))
        {
            ModelState.AddModelError("", "This email already exists!");
            return View(personInformation);
        }

        db.Entry(personInformation).State = EntityState.Modified; // error here
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(personInformation);
}

现在,我在不同的控制器编辑操作中拥有几乎完全相同的代码,并且工作正常。这里是:

public ActionResult Edit([Bind(Include = "ID,RNumber,DateCreated,PersonWhoCreated,deleted")] OtherTable oTable)
{
    if (ModelState.IsValid)
    {
        if (db.OtherTable.Any(x => x.RNumber.Equals(oTable.RNumber, StringComparison.CurrentCultureIgnoreCase) && x.ID != oTable.ID))
        {
            ModelState.AddModelError("RNumber", "This number already exists!");
            return View(oTable);
        }

        db.Entry(oTable).State = EntityState.Modified; // no error here.. goes through fine.
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(oTable);
}

我收到的错误:

附加类型为“ProjectName.Models.Information”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。使用“附加”等时可能会发生这种情况。

知道为什么会这样吗?

【问题讨论】:

  • Information 的主键是什么?您的实体集是否也启用了代理生成?
  • @PoweredByOrange ID 是 Information 的主键。如何检查代理生成?

标签: c# entity-framework asp.net-mvc-5


【解决方案1】:

db.Entry(personInformation).StatepersonInformation 对象附加到 EF 上下文,由于 EF 数据上下文先前加载了具有相同 ID 的不同 Information 实例(可能在前面的 Where() 中你正在做)。

至少有两个基本选项:

  • 第一个是为您的查询使用 AsNoTracking() 扩展,(如 db.Information.AsNoTracking())此扩展告诉 EF 数据上下文不要将从数据库中检索到的实体保留在内存中,这样您就可以将您的 personInformation 实体直接附加到上下文并设置修改后的状态。
  • 第二个选项是从 ef 数据上下文中检索实体并修改该实体(不是 personInformation 实例)。您可以使用db.Information.FindAsync 检索实体,如果之前已附加,EF 上下文将从内存中检索。
 var attachEntity = db.Information.FindAsync(personInformation.ID);
    attachEntity.ExampleValue = personInformation.ExampleValue;
    附加实体.ExampleValue2 = personInformation.ExampleValue2;
    ...
    等等

【讨论】:

  • 也适用于从数据库中删除 (AsNoTracking()),谢谢!
猜你喜欢
  • 2017-09-25
  • 2015-01-08
  • 2014-07-18
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多