SaveChanges()实体框架4.1的问题 [英] Problem with SaveChanges() Entity Framework 4.1

查看:79
本文介绍了SaveChanges()实体框架4.1的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having problem with saving the changes to database.

我正在控制器中更新模型A,但是当我使用SaveChanges()保存更改时,最终在数据库B中有重复的项.

I am updating the model A in my controller, however when I save the changes using SaveChanges() I end up having a duplicated item in database for B.

在调用UpdateModel()之后,我检查了Bs属性,这与我预期的一样,但是如果我检查Bs属性,则在调用SaveChanges()之后,我将看到Id完全不同(新的Id和新的Id条目).

After the UpdateModel() is called I inspected the Bs property and it was as I expected however right after the SaveChanges() is called if I inspect the Bs property I will see that the Id is completely different (new Id and new entry).

我的课与此类似:

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();
        }
    }

我做错什么了吗?

预先感谢

推荐答案

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

That is common behavior. The problem is that EF doesn't know that you attached an existing B so it automatically inserts a new record. You must say EF that the B is existing one by calling:

// here add B to the collection in the A and after that call:
dbContext.Entry<B>(someB).State = EntityState.Unchanged();

或通过附加B并将其添加到A中的集合之前(我不确定在ASP.NET MVC中使用UpdateModel时是否可以实现).

or by attaching B before you add it to collection in A (I'm not sure if this is possible when using UpdateModel in ASP.NET MVC).

dbContext.Bs.Attach(someB);
// now add B to the collection in the A

其他可能性是首先从数据库中加载B并将已加载的对象添加到A中的集合中,但这是数据库的附加往返行程.

Other possibility is to load B from database first and add loaded object to the collection in A but it is additional roundtrip to database.

int id = someB.Id;
var loadedB = dbCotnext.Bs.Single(b => b.Id == id);
someA.Bs.Add(loadedB);
dbContext.As.Add(someA);
dbContext.SaveChanges();

结论:每次调用Add时,整个对象图都会被跟踪为插入状态,除非您先附加相关实体(在将它们添加到插入的父级之前-第2和第3个示例),或者除非手动更改了相关状态添加父对象后,实体恢复为不变. (第一个示例).

Conclusion: Every time you call Add the whole object graph is tracked as inserted unless you attach related entities first (before you add them to inserted parent - the 2nd and 3rd example) or unless you manually change the state of related entities back to unchanged after adding the parent. (the 1st example).

这篇关于SaveChanges()实体框架4.1的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆