Linq - 在db.SaveChanges()调用中未保存的对象中的列表

时间:2013-04-08 14:14:14

标签: .net linq entity-framework linq-to-entities

我在将以下内容保存到数据库时遇到问题。

我有一个分支列表作为MessageType对象的一部分。我更新代码的第1部分中的分支列表,然后在第2部分中将分支列表保存到MessageType对象,然后调用db.SaveChanges()。不幸的是,新的分支列表没有持久化。

// section 1
 List<Branch> myBranches = new List<Branch>();
            foreach (int bid in branches)
            {
                var bran = db.Branches.Find(bid);
                if (bran != null)
                {
                    myBranches.Add(bran);
                }
            }
//section 2
            try
            {

                messagetype.SenderID = eSenderDB.MvcApplication.SenderID;
                messagetype.Branches = myBranches;
                foreach (Branch bra in messagetype.Branches)
                {
                    db.Entry(bra).State = EntityState.Modified;
                    db.SaveChanges();

                }
                //db.Entry(messagetype.Branches).State = EntityState.Modified;
                db.Entry(messagetype).State = EntityState.Modified;

                db.SaveChanges();

我的创建方法

[HttpPost]
        public ActionResult Create(MessageType messagetype, int[] branches)
        {
            List<Branch> myBranches = new List<Branch>();
            foreach (int bid in branches)
            {
                var bran = db.Branches.Find(bid);
                if (bran != null)
                {
                    myBranches.Add(bran);
                }
            }

            {
                messagetype.Branches = myBranches;
                messagetype.SenderID = eSenderDB.MvcApplication.SenderID;
                messagetype.OptIns = 0;
                db.MessageTypes.Add(messagetype);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(messagetype);
        }

2 个答案:

答案 0 :(得分:7)

您忘了将它们附加到上下文中。请尝试以下代码:

foreach (Branch bra in messagetype.Branches)
{
  db.Branches.Attach(bra);
  db.Entry(bra).State = EntityState.Modified;
  db.SaveChanges();
}

在旁注中,我质疑您在SaveChanges循环中调用foreach。你可以推迟保存到最后,它仍然可以正常工作。

答案 1 :(得分:1)

我猜这两种方法都是MVC中的Create和Edit控制器方法。

这里的问题是您的MessageType对象是通过MVC Binder直接从HTTP请求传递的。所以这是一个ViewModel。与此同时,您将此对象用作EntityModel。

这有点代码味道,因为表示层的需求通常可能与数据模型的需求不同。为每个对象分别提供一些好处。

要解决这个特殊问题,您有两个选择:

// Tell the database context to track the object and that the initial state is modified.
db.MessageTypes.Attach(messagetype); 
db.MessageTypes(messagetype).State = EntityState.Modified;

或者,

// Separate the entity object from the view object and merge the changes.
var messageTypeEntity = db.MessageTypes.Find(messageTypeViewModel.Id);
if(messageTypeEntity == null)
{
    ModelState.AddModelError(string.Empty, "The specified MessageType could not be found.");
    return View(messageTypeViewModel);
}

// Update messageTypeEntity from messageTypeViewModel
UpdateModel(messageTypeEntity);

db.SaveChanges();

阅读有关System.Web.Mvc.Controller.UpdateModel(...)的内容,并对SO here进行了一些讨论。