我在保存更改到数据库时遇到问题。
我正在更新我的控制器中的模型A,但是当我使用SaveChanges()保存更改时,我最终在数据库中为b创建了一个重复的项目
在UpdateModel()被调用后,我检查了b属性,正如我所期望的那样,但是在SaveChanges()被调用后,如果我检查了b属性,我会看到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();
}
}
我做错了什么吗?
Thanks in advance
这是常见的行为。问题是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
集合(我不确定在ASP中使用UpdateModel
时是否可能)。净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
时,整个对象图被跟踪为插入,除非你首先附加相关实体(在你将它们添加到插入的父元素之前-第二个和第三个例子),或者除非你在添加父元素后手动将相关实体的状态更改回不变。(第一个例子)。