批量删除在实体框架(bulk delete in entity framework)

2019-06-26 10:45发布

我想使用LINQ从表中批量删除记录。 有介绍如何做一个帖子: 批量删除的LINQ到实体

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

query.Delete();

但是,“删除”功能并没有在我的变种变量存在。
此外,功能“的SubmitChanges”没有我的情况下存在。

Answer 1:

有一个有趣的NuGet包, 让你做批量删除和更新 :



Answer 2:

目前尚无支持批量删除烤成实体框架。 它实际上的特点之一CodePlex上正在讨论现在EF是开源的。

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



Answer 3:

此代码添加了一个简单的扩展方法来将批量删除在实体框架查询你提供中引用的任何表中的所有数据的任何的DbContext。 它的工作原理简单地提取查询中涉及的所有表名,并试图通过发布“DELETE FROM表名”的SQL查询,这是在大多数类型的数据库的共同删除的数据。

使用时,只要做到这一点:

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

这将在连接到物联网实体店表中删除所有内容。

代码:

using System.Linq;
using System.Text.RegularExpressions;

namespace System.Data.Entity {

    public static class DbContextExtensions {

        /// <summary>
        /// Efficiently deletes all data from any database tables used by the specified entity framework query. 
        /// </summary>
        /// <typeparam name="TContext">The DbContext Type on which to perform the delete.</typeparam>
        /// <typeparam name="TEntity">The Entity Type to which the query resolves.</typeparam>
        /// <param name="ctx">The DbContext on which to perform the delete.</param>
        /// <param name="deleteQuery">The query that references the tables you want to delete.</param>
        public static void BulkDelete<TContext, TEntity>(this TContext ctx, Func<TContext, IQueryable<TEntity>> 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<Match>().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;

        }
    }
}


Answer 4:

我不喜欢这样,这似乎做工精细。 请让知道是否有一个原因,这是任何不好的做法。

        var customersToDelete = await ctx.Customers.Where(c => c.Email == "...").ToListAsync();

        foreach (var customerToDelete in customersToDelete)
        {
            ctx.Customers.Remove(customerToDelete);
        }

        await ctx.SaveChangesAsync();


文章来源: bulk delete in entity framework