当对象与上下文分离时,如何删除EF6中的对象列表

时间:2016-03-08 12:58:47

标签: c# entity-framework entity-framework-6

好的我可以删除EF6中的单个项目,如下所示:

public void DeleteUserGroup(MY_GROUPS ug)
{
    using (var context = new MYConn())
    {
        var entry = context.Entry(ug);
        if (entry.State == EntityState.Detached)
        {
            context.MY_GROUPS.Attach(ug);
        }

        context.MY_GROUPS.Remove(ug);
        context.SaveChanges();
    }
}

如果此方法从单个MY_GROUPS实例更改为List<MY_GROUPS>,我将如何处理删除?

是否有一种更有效的方法,只需执行foreach并一次设置一个状态?

更新: 我已经使用了与RemoveRange方法类似的方法。 但是我收到了一个错误:

  

无法删除该对象,因为在该对象中找不到该对象   ObjectStateManager。

我正在寻找将对象列表附加到上下文的最佳方法,以便我可以删除它们。

6 个答案:

答案 0 :(得分:2)

您可以使用RemoveRange

context.MY_GROUPS.RemoveRange(context.MY_GROUPS.Where(x => x.columnName== "Foo"));

你也可以像这样使用ForEach

context.MY_GROUPS.Where(x => x.columnName == "Foo").ToList().ForEach(context.DeleteObject);
context.SaveChanges();

您也可以使用ObjectContext.ExecuteStoreCommand Method作为另一种方法。

答案 1 :(得分:2)

为了能够删除记录,您需要确保ObjectContext正在跟踪它们。现在你有了分离的对象,你的上下文不知道它们,所以不可能删除它们。删除它们的一种方法是像你说的那样,Attach将所有对象都添加到上下文中,然后删除它们。另一种方法是从数据库中获取记录,以便删除它们:

//Find all groups in database with an Id that is in your group collection 'ug'
var groups = context.My_Groups.Where(g => ug.Any(u => u.Id == g.Id));
context.My_Groups.RemoveRange(groups);
context.SaveChanges();

但请注意,即使使用RemoveRange,也会将删除命令发送到要删除的数据库 / 项目。 RemoveRangeRemove之间的唯一区别是,第一个只会调用DetectChanges一次,这可以真正提高性能。

答案 2 :(得分:1)

迭代您的收藏并为每个

设置Deleted
groups.ForEach(group => ctx.Entry(group).State = EntityState.Deleted);
ctx.SaveChanges();

答案 3 :(得分:0)

使用.RemoveRange()实现EntityFramework 6+更容易。

    public void DeleteUserGroup(List<MY_GROUPS> ug)
    {
        using (var context = new MYConn())
        {
            context.MY_GROUPS.RemoveRange(ug);
            context.SaveChanges();
        }
    }

答案 4 :(得分:0)

使用品牌为IEnumerable的{​​{3}}提供的solution

context.Brands.RemoveRange(context.Brands.Where(cb => brands.Any(b => b.Id == cb.Id)));

我收到以下错误:

  

无法创建类型&#39; SomeCompany.SomeApp.DB.Entities.Brand&#39;的常量值。在此上下文中仅支持基本类型或枚举类型。

通过使用DBSet扩展方法将品牌IEnumerable转换为AsEnumerable()来解决问题:

context.Brands.RemoveRange(context.Brands.AsEnumerable().Where(cb => brands.Any(b => b.Id == cb.Id)));

这对我有用。

答案 5 :(得分:0)

我发现这对我有用。在调用保存更改之前,我是循环执行的。我希望它仅创建delete sql命令就可以了。

http://www.entityframeworktutorial.net/entityframework6/delete-disconnected-entity-in-entity-framework.aspx

// disconnected entity to be deleted
var student = new Student(){ StudentId = 1 };

using (var context = new SchoolDBEntities())
{
    context.Entry(student).State = System.Data.Entity.EntityState.Deleted;    

    context.SaveChanges();
}