使用RemoveRange()批量删除行

时间:2014-03-03 20:43:28

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

我正在尝试从表中删除多行。

在常规SQL Server中,这很简单:

DELETE FROM Table
WHERE
    Table.Column = 'SomeRandomValue'
    AND Table.Column2 = 'AnotherRandomValue'

在实体框架6中,他们引入了RemoveRange()方法 但是,当我使用它时,Entity Framework不是使用我提供的where子句删除行,而是查询数据库以获取与where子句匹配的所有行,并使用其主键逐个删除它们。

这是EntityFramework的当前限制吗? 或者我使用RemoveRange()错了吗?

以下是我使用RemoveRange()的方式:

db.Tables.RemoveRange(
    db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomValue')
);

8 个答案:

答案 0 :(得分:3)

我认为我们达到了EF的限制。 有时您只需使用ExecuteSqlCommand来保持高效。

答案 1 :(得分:3)

您正在寻找的是批量删除库,它可以在不加载实体的情况下从LINQ查询中删除数据库中的多条记录。

存在支持此功能的多个库。

您可以在此处找到列表:Entity Framework Batch Delete Library

免责声明:我是该项目的所有者Entity Framework Plus

// using Z.EntityFramework.Plus; // Don't forget to include this.

// DELETE directly in SQL (without loading entities)
db.Tables.Where(_ => _.Column == 'SomeRandomValue'
                     && _.Column2 == 'AnotherRandomValue')
         .Delete();

// DELETE using a BatchSize      
db.Tables.Where(_ => _.Column == 'SomeRandomValue'
                     && _.Column2 == 'AnotherRandomValue')
         .Delete(x => x.BatchSize = 1000);

维基:EF+ Batch Delete

答案 2 :(得分:1)

有点破,试试

db.Tables.RemoveRange(
    db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList()
);
db.SaveChanges();

答案 3 :(得分:1)

var db1 =  db.Tables
        .Where(_ => _.Column == 'SomeRandomValue'
            && _.Column2 == 'AnotherRandomeValue').AsEnumerable().ToList();
db.Tables.RemoveRange(db1);
db.SaveChanges();

使用变量存储可移动列表并将其传递给RemoveRange()。

我通常喜欢这样,那就是工作。 希望这也适用于你的情况。

答案 4 :(得分:0)

为什么你不只是有一个适配器到数据库,只是发送适当的删除命令,如你的例子?

答案 5 :(得分:0)

退一步思考。您真的想从数据库中下载记录以删除它们吗?仅仅因为你可以做到这一点并不是一个好主意。

也许您可以考虑使用存储过程从数据库中删除项目? EF也允许这样做......

答案 6 :(得分:0)

我自己正在处理这个问题,并且同意Adi - 只需使用sql。

我正在清理日志表中的旧行,而EF RemoveRange需要3分钟才能完成3秒内完成的操作:

DELETE FROM LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < -6

Date是包含日期的列的名称。要使其正确,请使用参数,当然,如下所示:

  context.Database.ExecuteSqlCommand
      ("DELETE FROM  LogEntries WHERE DATEDIFF(day, GETDATE(), Date) < @DaysOld", new System.Data.SqlClient.SqlParameter(
                        "DaysOld", - Settings.DaysToKeepDBLogEntries));

请注意,我的案例涉及很多行。当我启动项目并且没有大量数据时,RemoveRange工作正常。

答案 7 :(得分:0)

我也遇到了这个问题,这是我使用LoreSoft的名为 entityframework.extended 的库的解决方法(您可以从nuget包管理器中获取它):

1。您首先查询他们的列表。 2.然后使用.Delete(),它是.extended库中的函数。

var removeList = db.table.Where(_ => _.Column == 'SomeRandomValue'&& _.Column2 == 'AnotherRandomValue')        
removeList .Delete();

注意:根据Entity Framework EF extended,截至撰写本文时,此objectframework.extended已被弃用。因此,可能需要考虑实体框架和库。虽然我还没有对plus扩展名进行测试,但是我可以确认使用.extended库可以正常工作。