wake-up-neo.com

Massenlöschen von Zeilen mit RemoveRange ()

Ich versuche, mehrere Zeilen aus einer Tabelle zu löschen.

In normalen SQL Server wäre dies einfach so:

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

In Entity Framework 6 wurde die RemoveRange () -Methode eingeführt.
Wenn ich es jedoch verwende, löscht Entity Framework die Datenbank, anstatt Zeilen mit den von mir angegebenen where-Klauseln zu löschen, um alle Zeilen abzurufen, die den where-Klauseln entsprechen, und löscht sie nacheinander mit ihren Primärschlüsseln.

Ist dies die aktuelle Einschränkung von EntityFramework? Oder verwende ich RemoveRange() falsch?

Im Folgenden verwende ich RemoveRange():

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

Ich denke, wir haben hier eine Einschränkung von EF .. erreicht .. Manchmal müssen Sie nur ExecuteSqlCommand verwenden, um performant zu bleiben.

3
Adi

Was Sie suchen, ist eine Batch Delete Library, die mehrere Datensätze in einer Datenbank aus einer LINQ-Abfrage löscht, ohne Entitäten zu laden.

Es gibt mehrere Bibliotheken, die diese Funktion unterstützen.

Sie finden die Liste hier: Entity Framework Batch Delete Library

Disclaimer: Ich bin der Eigentümer des Projekts 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);

Wiki: EF + Batch Delete

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

Verwenden Sie eine Variable zum Speichern der entfernbaren Liste und übergeben Sie diese an RemoveRange ().

Normalerweise mag ich das und das ist Arbeit. Hoffnung. Das funktioniert auch in Ihrem Fall.

1
AKASH

Es ist ein bisschen kaputt, versuche es

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

Ich beschäftige mich damit und stimme mit Adi überein - benutze einfach sql. 

Ich bereinige alte Zeilen in einer Protokolltabelle und EF RemoveRange brauchte 3 Minuten, um dasselbe zu tun, was dies in 3 Sekunden tat:

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

Datum ist der Name der Spalte, die das Datum enthält. Um dies zu korrigieren, verwenden Sie natürlich einen Parameter wie folgt:

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

Beachten Sie, dass in meinem Fall viele Zeilen enthalten sind. Als ich das Projekt startete und nicht viele Daten hatte, funktionierte RemoveRange gut. 

0
user7369569

Treten Sie zurück und denken Sie nach. Möchten Sie die Datensätze wirklich aus der Datenbank herunterladen, um sie zu löschen? Nur weil Sie es nicht können, ist es keine gute Idee. 

Vielleicht möchten Sie die Elemente mit einer gespeicherten Prozedur aus der Datenbank löschen? EF erlaubt das auch ...

0

Ich bin auch auf dieses Problem gestoßen. Dies ist meine Problemumgehung mit einer Bibliothek namens entityframework.extended von LoreSoft (die Sie von Nuget Package Manager erhalten können). :

1. Sie fragen zuerst Ihre Liste ab. 2.Verwenden Sie dann .Delete (), eine Funktion aus der erweiterten Bibliothek.

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

Hinweis: Gemäß Entity Framework EF extended ist dieses entityframework.extended zum Zeitpunkt des Schreibens veraltet. Daher muss man möglicherweise Entityframework plus Bibliothek berücksichtigen. Ich habe zwar nicht auf der Plus-Erweiterung getestet, kann aber bestätigen, dass es mit der erweiterten Bibliothek funktioniert.

0
csamleong

Warum haben Sie nicht einfach einen Adapter für die Datenbank und senden einfach den entsprechenden Löschbefehl wie in Ihrem Beispiel?

0
Shar1er80