ASP.NET MVC - Attaching an entity of type #39;MODELNAME#39; failed because another entity of the same type already has the same primary key value(ASP.NET MVC - 附加类型为“MODELNAME的实体失败,因为同一类型的另一个实体已经具有相同的主键值)
问题描述
In a nutshell the exception is thrown during POSTing wrapper model and changing the state of one entry to 'Modified'. Before changing the state, the state is set to 'Detached' but calling Attach() does throw the same error. I'm using EF6.
Please find my code below(model names have been changed to make it easier to read)
Model
// Wrapper classes
public class AViewModel
{
public A a { get; set; }
public List<B> b { get; set; }
public C c { get; set; }
}
Controller
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (!canUserAccessA(id.Value))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
var aViewModel = new AViewModel();
aViewModel.A = db.As.Find(id);
if (aViewModel.Receipt == null)
{
return HttpNotFound();
}
aViewModel.b = db.Bs.Where(x => x.aID == id.Value).ToList();
aViewModel.Vendor = db.Cs.Where(x => x.cID == aViewModel.a.cID).FirstOrDefault();
return View(aViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(AViewModel aViewModel)
{
if (!canUserAccessA(aViewModel.a.aID) || aViewModel.a.UserID != WebSecurity.GetUserId(User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
if (ModelState.IsValid)
{
db.Entry(aViewModel.a).State = EntityState.Modified; //THIS IS WHERE THE ERROR IS BEING THROWN
db.SaveChanges();
return RedirectToAction("Index");
}
return View(aViewModel);
}
As shown above line
db.Entry(aViewModel.a).State = EntityState.Modified;
throws exception:
Attaching an entity of type 'A' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Does anybody see anything wrong in my code or understand in what circumstances it would throw such error during editing a model?
Problem SOLVED!
Attach
method could potentially help somebody but it wouldn't help in this situation as the document was already being tracked while being loaded in Edit GET controller function. Attach would throw exactly the same error.
The issue I encounter here was caused by function canUserAccessA()
which loads the A entity before updating the state of object a. This was screwing up the tracked entity and it was changing state of a object to Detached
.
The solution was to amend canUserAccessA()
so that the object I was loading wouldn't be tracked. Function AsNoTracking()
should be called while querying the context.
// User -> Receipt validation
private bool canUserAccessA(int aID)
{
int userID = WebSecurity.GetUserId(User.Identity.Name);
int aFound = db.Model.AsNoTracking().Where(x => x.aID == aID && x.UserID==userID).Count();
return (aFound > 0); //if aFound > 0, then return true, else return false.
}
For some reason I couldnt use .Find(aID)
with AsNoTracking()
but it doesn't really matter as I could achieve the same by changing the query.
Hope this will help anybody with similar problem!
这篇关于ASP.NET MVC - 附加类型为“MODELNAME"的实体失败,因为同一类型的另一个实体已经具有相同的主键值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:ASP.NET MVC - 附加类型为“MODELNAME"的实体失败,因为同一类型的另一个实体已经具有相同的主键值
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 如何用自己压缩一个 IEnumerable 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- 输入按键事件处理程序 2022-01-01