SaveChanges()Entity Framework 4.1的问题

时间:2011-04-17 12:44:14

标签: many-to-many entity-relationship entity-framework-4.1

我在将更改保存到数据库时遇到问题。

我正在更新控制器中的模型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();
        }
    }

我做错了吗?

提前致谢

1 个答案:

答案 0 :(得分:8)

这是常见的行为。问题是EF不知道您附加了现有的B,因此它会自动插入新记录。您必须通过调用:

来说EF 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个例子)。