我正在尝试从表中删除多行。
在常规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')
);
答案 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);
答案 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库可以正常工作。