附加类型为“X”的实体失败,因为同一类型的另一个实体
我在我的代码中偶然发现了一个奇怪的错误。 以前工作过,但现在有时工作。
我正在使用EF6来编辑具有某种关系的实体。 不编辑我’附加’它们的关系(参见示例代码)。
public void EditA(A ThisIsA, B ThisIsB) { using (var Context = new LDZ_DEVEntities()) { Context.As.Attach(ThisIsA); var b = Context.Bs.FirstOrDefault(x => x.BId == ThisIsB.BId); //var b = Context.Bs.Find(ThisIsB.BId); if (b != null) Context.Bs.Attach(b); else b = ThisIsB; if (bC != null) Context.Cs.Attach(bC); ThisIsA.Bs.Add(b); Context.SaveChanges(); } }
我编辑了免费精选名字大全以保持简单。
以下行
Context.Cs.Attach(bC);
抛出此错误:
附加类型为“C”的实体失败,因为相同类型的另一个实体已具有相同的主键值。 如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。 这可能是因为某些实体是新的并且尚未收到数据库生成的键值。 在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
引入此行是因为所有C实体都是静态实体。 我从不想要创建一个C. 如果我删除此行,每次我将A添加到A; 创建了一个C. 这是不可取的。
额外信息:
A有一个B列表
B有一个C.
在我的软件中的多个位置调用此EditA()方法。 仅在循环(导入)中调用方法时才会出现此错误。 在处理第一条记录时没有问题。 但是我在第一个记录之后得到了记录中的错误。
我已经阅读了这些问题和答案,但它们并不适合我:
-
ASP.NET MVC – 附加“MODELNAME”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值
-
附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值
我修好了它。
他在Fabio Luz的回答中说:
//如果已从上下文加载A.
//不要附上它
//如果它是在上下文之外创建的
//Context.Entry(ThisIsA).State = EntityState.Modified;
这让我思考,所以我编写了我的代码:
public void EditA(A ThisIsA, B ThisIsB) { using (var Context = new LDZ_DEVEntities()) { var a = Context.As.Find(ThisIsA.AId); //var b = Context.Bs.FirstOrDefault(x => x.BId == ThisIsB.BId); var b = Context.Bs.Find(ThisIsB.BId); if (b != null) Context.Bs.Attach(b); else b = ThisIsB; if (bC != null) Context.Cs.Attach(bC); a.Bs.Add(b); Context.SaveChanges(); } }
变更摘要:
起初我删除了附加C,结果创建了一个新实体。 所以我改变了这个改变。
特别感谢Fabio Luz。 没有你的帮助我不可能做到这一点!
请查看以下链接https://msdn.microsoft.com/en-us/data/jj592676.aspx
如果您知道某个实体已经存在于数据库中但可能已对其进行了更改,那么您可以告诉上下文附加实体并将其状态设置为Modified。 例如:
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" }; using (var context = new BloggingContext()) { context.Entry(existingBlog).State = EntityState.Modified; // Do some more work... context.SaveChanges(); }
注意:您不必对所有对象(A,B和C)执行此操作,只需使用A.
编辑1
根据您的评论,试试这个:
//check if var _b = Context.Bs.Find(ThisIsB.BId); if (_b != null) //b doesn't exist, then add to the context //make sure that the primary key of A is set. //_b.PrimaryKeyOfA = someValue; Context.Bs.Add(_b); else //b already exists, then modify the properties //make sure that the primary key of A is set. Context.SaveChanges();
编辑2
我没有测试,但它应该工作。
public void EditA(A ThisIsA, B ThisIsB) { using (var Context = new LDZ_DEVEntities()) { //if A has been loaded from context //dont attach it //if it has been created outside of the context //Context.Entry(ThisIsA).State = EntityState.Modified; var _b = Context.Bs.Find(ThisIsB.BId); if (_b == null) { _b = ThisIsB; } ThisIsA.Bs.Add(_b); Context.SaveChanges(); } }
另一种方法,取决于您的情况,是简单地分离实体状态。
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Modify(Model model) { if (model.Image == null) { Model item = db.Model.Find(model.Name); // Get the Content needed: model.Image = item.Image; // Detach the Comparison State: db.Entry(item).State = EntityState.Detached; } if (ModelState.IsValid) { db.Entry(model).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(model); }
通过这样做: db.Entry(item).State = EntityState.Detached;
EntityFramework的状态仍然完好无损,您可以将更改保存到数据库(db)中。
希望这可以帮助!
附加或设置实体修改不适用于我的情况但这对我来说工作:
上述就是C#学习教程:附加类型为“X”的实体失败,因为同一类型的另一个实体分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public int GuardarAsociacionesBonos(List bonos) { if (!bonos.Any()) return bonos.Count; using (var contexto = new TouchERPEntities()) { foreach (var bono in bonos) { var existe = contexto.O_Bono_ConfiguracionPago.SingleOrDefault(x => x.IDBono == bono.IDBono && x.IDConfiguracionPago == bono.IDConfiguracionPago); if (existe != null && existe.IDBonoConfigPago != 0) { bono.IDBonoConfigPago = existe.IDBonoConfigPago; contexto.Entry(existe).CurrentValues.SetValues(bono); } else { contexto.O_Bono_ConfiguracionPago.Add(bono); } } contexto.SaveChanges(); } return bonos.Count; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1007539.html