使用MVC3 Entity Framework 4.3 Code First从集合中删除chlid对象

本文关键字:集合 删除 对象 chlid First Code Entity MVC3 Framework 使用 | 更新日期: 2023-09-27 18:28:51

我发现了许多与我的问题非常相似的帖子,但它们似乎都使用了DeleteObject()方法,而在我使用的EF版本中似乎不存在这种方法!(尽管我很可能找错地方了)

不管怎样,我的问题。我有两个类,UserEmail,其中用户可以拥有许多电子邮件。我有一个编辑表单,可以很高兴地编辑每个用户的所有电子邮件地址。我希望通过清除编辑表单中的文本框来删除每个电子邮件地址(稍后使用与每个框关联的删除按钮触发的JavaScript功能来完成)。为此,当数据返回时,我循环查看所有电子邮件地址,并测试地址属性是否为null,此时我想完全删除Email对象。下面是我的编辑控制器,它(不)做业务:

[HttpPost]
public ActionResult Edit(int id, User User)
{
    try
    {
        foreach (Email Email in User.Emails)
        {
            if (Email.Address == null)
            {
                User.Emails.Remove(Email);
            }
            else
            {
                db.Entry(Email).State = EntityState.Modified;
            }
        }
        db.Entry(User).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    catch
    {
        return RedirectToAction("Index");
    }
}

这在一定程度上起到了作用,使用调试器我可以看到它很高兴地从User中删除Email对象,但一旦它完成了这一操作,当它试图再次通过循环时就会抛出异常:

Message=Collection was modified; enumeration operation may not execute.

我的问题是:删除Email对象的正确方法是什么,不仅从User中删除,而且从我的数据库中删除?

提前感谢;-)

编辑:

我修改了我的控制器,创建了两个列表,一个用于带有和地址的Emails,另一个用于地址为空的列表,并循环通过这些列表:

[HttpPost]
public ActionResult Edit(int id, User User)
{
    try
    {
        var notNullEmails = User.Emails.Where(e => e.Address != null).ToList();
        foreach (Email Email in notNullEmails)
        {
            db.Entry(Email).State = EntityState.Modified;
        }
        var isNullEmails = User.Emails.Where(e => e.Address == null).ToList();
        foreach (Email Email in isNullEmails)
        {
            db.Emails.Remove(Email);
        }
        db.Entry(User).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    catch
    {
        return RedirectToAction("Index");
    }
}

但这导致了这个例外:

Message=The object cannot be deleted because it was not found in the ObjectStateManager.

因此,我调整了用于空地址的foreach,以明确地将要删除的电子邮件拉到上下文中,如下所示:

var isNullEmails = User.Emails.Where(e => e.Address == null).ToList();
foreach (Email Email in isNullEmails)
{
    Email EmailToDelete = db.Emails.Find(Email.Id);
    db.Emails.Remove(EmailToDelete);
}

但这导致了这个例外:

Message=Value cannot be null.

我想我能做到这一点要感谢你们,但我需要更多的帮助:-)

使用MVC3 Entity Framework 4.3 Code First从集合中删除chlid对象

您有两个不同的问题:

一种是,在迭代集合时不能从集合中删除项。使用.ToList()遍历我制作的列表副本。

另一种是,调用您正在调用的Remove()方法只是删除与User的关系,而不是从数据库中实际删除它。如果数据库强制执行,这将生成引用完整性错误

相反,您希望对电子邮件数据库集调用Remove。

context.emails.Remove(email);

Remove()是DbContext使用的方法。DeleteObject和RemoveObject是较旧的/可供选择的API

我知道你说过不使用DeleteObject,但我也有同样的问题,我认为我应该在这里为其他搜索这个问题的人发布答案:


int i = User.Emails.Count - 1;
while (true)
{
  if (i<0)
  {
     break;
  }
  Db.Emails.DeleteObject(User.Emails.ElementAt<Email>(i));
  i--;
}

我知道这真的很旧,但我想我可能应该用我发现的实际有效的方法来回答它:

foreach(Email email in User.Emails)
{
    if(string.IsNullOrEmpty(email.Address))
    {
        db.Entry(email).State = System.Data.EntityState.Deleted;
    }
}
db.SaveChanges();

我认为这是迄今为止我见过的最简单的解决方案,但如果有更好的方法,请随时纠正我。