entity framework中的批量删除

我想使用linq批量删除表中的记录。 有一篇post描述了如何做到这一点: LINQ to Entities中的批量删除

var query = from c in ctx.Customers where c.SalesPerson.Email == "..." select c; query.Delete(); 

但是我的var变量中不存在“删除”function。
此外,我的上下文中不存在“SubmitChanges”function。

有一个有趣的NuGet包, 可以让你进行批量删除和更新 :

entity framework中目前不支持批量删除。 它实际上是在codeplex上讨论的function之一,现在EF是开源的。

EntityFramework.Extended提供批量删除支持(你可以在nuget中找到它)但是我的经验是它有一些性能问题。

此代码为任何DbContext添加了一个简单的扩展方法,该方法将批量删除您提供的entity framework查询中引用的任何表中的所有数据。 它的工作原理是简单地提取查询中涉及的所有表名,并尝试通过发出“DELETE FROM tablename”SQL查询来删除数据,这在大多数类型的数据库中都很常见。

要使用,只需执行以下操作:

 myContext.BulkDelete(x => x.Things); 

这将删除链接到Things实体商店的表中的所有内容。

代码:

 using System.Linq; using System.Text.RegularExpressions; namespace System.Data.Entity { public static class DbContextExtensions { ///  /// Efficiently deletes all data from any database tables used by the specified entity framework query. ///  /// The DbContext Type on which to perform the delete. /// The Entity Type to which the query resolves. /// The DbContext on which to perform the delete. /// The query that references the tables you want to delete. public static void BulkDelete(this TContext ctx, Func> deleteQuery) where TContext : DbContext { var findTables = new Regex(@"(?:FROM|JOIN)\s+(\[\w+\]\.\[\w+\])\s+AS"); var qry = deleteQuery(ctx).ToString(); // Get list of all tables mentioned in the query var tables = findTables.Matches(qry).Cast().Select(m => m.Result("$1")).Distinct().ToList(); // Loop through all the tables, attempting to delete each one in turn var max = 30; var exception = (Exception)null; while (tables.Any() && max-- > 0) { // Get the next table var table = tables.First(); try { // Attempt the delete ctx.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", table)); // Success, so remove table from the list tables.Remove(table); } catch (Exception ex) { // Error, probably due to dependent constraint, save exception for later if needed. exception = ex; // Push the table to the back of the queue tables.Remove(table); tables.Add(table); } } // Error error has occurred, and cannot be resolved by deleting in a different // order, then rethrow the exception and give up. if (max <= 0 && exception != null) throw exception; } } } 

我这样做似乎工作得很好。 请知道是否有任何理由说这是不好的做法。

  var customersToDelete = await ctx.Customers.Where(c => c.Email == "...").ToListAsync(); foreach (var customerToDelete in customersToDelete) { ctx.Customers.Remove(customerToDelete); } await ctx.SaveChangesAsync();