bulk delete nel framework di quadro

Mi piacerebbe effettuare il bulk dei record da una tabella usando linq. C’è un post che descrive come eseguirlo: eliminazione collettiva in LINQ alle quadro

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

Ma la funzione “Elimina” non esiste nella mia variabile var.
Inoltre, la funzione “SubmitChanges” non esiste nel mio contesto.

C’è un interessante pacchetto NuGet che ti consente di effettuare eliminazioni e aggiornamenti in batch :

Al momento non è stata eliminata l’eliminazione collettiva supportata in Entity Framework. In realtà è una delle funzionalità in discussione su codeplex ora EF è open-source.

EntityFramework.Extended fornisce il supporto per l’eliminazione batch (puoi trovarlo in nuget), tuttavia la mia esperienza è che presenta alcuni problemi di prestazioni.

Questo codice aggiunge un metodo di estensione semplice a qualsiasi DbContext che eliminerà in blocco tutti i dati in qualsiasi tabella a cui si fa riferimento all’interno della query del framework di quadro fornita dall’utente. Funziona semplicemente estraendo tutti i nomi di tabella coinvolti nella query e tentando di eliminare i dati inviando una query SQL “DELETE FROM tablename”, che è comune nella maggior parte dei tipi di database.

Per usare, basta fare questo:

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

che cancellerà tutto nella tabella collegata all’archivio delle quadro Things.

Il codice:

 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; } } } 

Lo faccio come questo che sembra funzionare bene. Per favore, fai sapere se c’è una ragione per cui questa è una ctriggers pratica in qualsiasi modo.

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