392 Stimmen

Wie kann ich mehrere Zeilen in Entity Framework löschen (ohne foreach)

Ich lösche mehrere Elemente aus einer Tabelle mit Entity Framework. Es gibt keinen Fremdschlüssel / übergeordnetes Objekt, so dass ich dies nicht mit OnDeleteCascade behandeln kann.

Im Moment mache ich das:

var widgets = context.Widgets
    .Where(w => w.WidgetId == widgetId);

foreach (Widget widget in widgets)
{
    context.Widgets.DeleteObject(widget);
}
context.SaveChanges();

Es funktioniert, aber das foreach stört mich. Ich verwende EF4, aber ich möchte kein SQL ausführen. Ich möchte nur sicherstellen, dass ich nichts verpasse - das ist so gut wie es geht, richtig? Ich kann es mit einer Erweiterungsmethode oder einem Helfer abstrahieren, aber irgendwo werden wir immer noch ein foreach ausführen, richtig?

1voto

Hugo Nava Kopp Punkte 2548

Sie können auch die DeleteAllOnSubmit() Methode, indem Sie ihr Ihre Ergebnisse in einer generische Liste Auf diese Weise reduziert sich Ihr foreach auf eine Zeile Code:

List<Widgets> widgetList = context.Widgets
              .Where(w => w.WidgetId == widgetId).ToList<Widgets>();

context.Widgets.DeleteAllOnSubmit(widgetList);

context.SubmitChanges();

Wahrscheinlich wird aber intern noch eine Schleife verwendet.

1voto

Steve Greene Punkte 11559

Die Antwort von Thanh hat für mich am besten funktioniert. Sie löschte alle meine Datensätze in einer einzigen Serverreise. Ich kämpfte mit tatsächlich Aufruf der Erweiterung Methode, so dachte ich würde meine teilen (EF 6):

Ich habe die Erweiterungsmethode zu einer Hilfsklasse in meinem MVC-Projekt hinzugefügt und den Namen in "RemoveWhere" geändert. Ich injiziere einen dbContext in meine Controller, aber Sie könnten auch eine using .

// make a list of items to delete or just use conditionals against fields
var idsToFilter = dbContext.Products
    .Where(p => p.IsExpired)
    .Select(p => p.ProductId)
    .ToList();

// build the expression
Expression<Func<Product, bool>> deleteList = 
    (a) => idsToFilter.Contains(a.ProductId);

// Run the extension method (make sure you have `using namespace` at the top)
dbContext.RemoveWhere(deleteList);

Dadurch wurde eine einzige Löschanweisung für die Gruppe erzeugt.

1voto

Seagull Punkte 3038

Ich habe mir eine tolle Bibliothek ausgedacht Zack.EFCore.Batch . Es wandelt Ihren Ausdruck in einfache DELETE FROM .... WHERE Abfrage. (Wie einige Antworten vorgeschlagen) https://github.com/yangzhongke/Zack.EFCore.Batch

Das Anwendungsbeispiel:

await ctx.DeleteRangeAsync<Book>(b => b.Price > n);

En Zack.EFCore.Batch Bibliothek hat viele Vorteile gegenüber Z.EntityFramework.Extended https://entityframework-extensions.net/ die keine echten Async-Methoden hat. (Sie sind nur Wrapper um Sync-Methoden) Sie können viele unerwartete Probleme durch die Verwendung dieser Bibliothek in hoher Belastung Umgebung erhalten.

0voto

Erçin Dedeoğlu Punkte 4262

EF 6.=>

var assignmentAddedContent = dbHazirBot.tbl_AssignmentAddedContent.Where(a =>
a.HazirBot_CategoryAssignmentID == categoryAssignment.HazirBot_CategoryAssignmentID);
dbHazirBot.tbl_AssignmentAddedContent.RemoveRange(assignmentAddedContent);
dbHazirBot.SaveChanges();

-1voto

maXXis Punkte 35

Beste : in EF6 => .RemoveRange()

Beispiel:

db.Table.RemoveRange(db.Table.Where(x => Field == "Something"));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X