我在将更改保存到数据库时遇到问题。
我正在更新控制器中的模型A,但是当我使用SaveChanges()保存更改时,我最终在B数据库中有一个重复的项目。
在调用UpdateModel()之后,我检查了Bs属性并且它正如我预期的那样在调用SaveChanges()之后如果我检查Bs属性,我将看到Id完全不同(新Id和新条目)。
我的课程类似于:
public class A
{
[HiddenInput(DisplayValue = false)]
public int AId { get; set; }
public string Name { get; set; }
public virtual ICollection<B> Bs{ get; set; }
}
public class B
{
[HiddenInput(DisplayValue = false)]
public int BId { get; set; }
public string Name { get; set; }
public virtual ICollection<A> As{ get; set; }
}
我的控制器是这样的:
[HttpPost]
public ActionResult Edit(A theA)
{
try
{
db.Entry(theA).State = EntityState.Modified;
foreach (var item in theA.Bs)
{
db.Entry(item).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
我做错了吗?
提前致谢
答案 0 :(得分:8)
这是常见的行为。问题是EF不知道您附加了现有的B
,因此它会自动插入新记录。您必须通过调用:
B
是现有的
// here add B to the collection in the A and after that call:
dbContext.Entry<B>(someB).State = EntityState.Unchanged();
或在将B
添加到A
中的集合之前附加UpdateModel
(我不确定在ASP.NET MVC中使用dbContext.Bs.Attach(someB);
// now add B to the collection in the A
时是否可以这样做。)
B
其他可能性是首先从数据库加载A
并将加载的对象添加到int id = someB.Id;
var loadedB = dbCotnext.Bs.Single(b => b.Id == id);
someA.Bs.Add(loadedB);
dbContext.As.Add(someA);
dbContext.SaveChanges();
中的集合中,但它是数据库的附加往返。
Add
结论:每次调用{{1}}时,整个对象图都会被跟踪为插入,除非您首先附加相关实体(在将它们添加到插入的父项之前 - 第二个和第三个示例之前),或者除非您手动更改状态添加父项后,相关实体的数量不变。 (第1个例子)。