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?

31voto

Marcelo Mason Punkte 6232

Für alle, die EF5 verwenden, kann die folgende Erweiterungsbibliothek verwendet werden: https://github.com/loresoft/EntityFramework.Extended

context.Widgets.Delete(w => w.WidgetId == widgetId);

22voto

Nguyen Van Thanh Punkte 763

Entity Framework Kern

3.1 3.0 2.2 2.1 2.0 1.1 1.0

using (YourContext context = new YourContext ())
{
    var widgets = context.Widgets.Where(w => w.WidgetId == widgetId);
    context.Widgets.RemoveRange(widgets);
    context.SaveChanges();
}

Zusammenfassung :

Entfernt die angegebene Sammlung von Entitäten aus dem Kontext, der der Menge zugrunde liegt zugrundeliegenden Kontext, wobei jede Entität in den Status "Gelöscht" versetzt wird, so dass sie aus der Datenbank gelöscht wird aus der Datenbank gelöscht wird, wenn SaveChanges aufgerufen wird.

Bemerkungen :

Beachten Sie, dass wenn System.Data.Entity.Infrastructure.DbContextConfiguration.AutoDetectChangesEnabled auf true gesetzt ist (was der Standard ist), dann wird DetectChanges einmal aufgerufen aufgerufen, bevor eine Entität gelöscht wird, und wird nicht erneut aufgerufen. Das bedeutet, dass in einigen Situationen RemoveRange wesentlich besser funktionieren kann als der mehrfache Aufruf von Remove mehrmals aufrufen würde. Beachten Sie, dass wenn eine Entität im Kontext im Zustand Added existiert, dann wird diese Methode bewirken, dass es aus dem Kontext herausgelöst wird. Der Grund dafür ist dass eine hinzugefügte Entität nicht in der Datenbank existiert, so dass der Versuch, sie zu löschen es nicht sinnvoll ist.

13voto

Edward Brey Punkte 37840

Es scheint immer noch verrückt zu sein, etwas vom Server zurückholen zu müssen, nur um es zu löschen, aber zumindest ist es viel einfacher, nur die IDs zurückzubekommen, als alle Entitäten abzurufen:

var ids = from w in context.Widgets where w.WidgetId == widgetId select w.Id;
context.Widgets.RemoveRange(from id in ids.AsEnumerable() select new Widget { Id = id });

9voto

mnsr Punkte 12107

EF 6.1

public void DeleteWhere<TEntity>(Expression<Func<TEntity, bool>> predicate = null) 
where TEntity : class
{
    var dbSet = context.Set<TEntity>();
    if (predicate != null)
        dbSet.RemoveRange(dbSet.Where(predicate));
    else
        dbSet.RemoveRange(dbSet);

    context.SaveChanges();
} 

Verwendung:

// Delete where condition is met.
DeleteWhere<MyEntity>(d => d.Name == "Something");

Or:

// delete all from entity
DeleteWhere<MyEntity>();

4voto

UUHHIVS Punkte 1139

Hierfür können Sie Erweiterungsbibliotheken wie EntityFramework.Extended oder Z.EntityFramework.Plus.EF6 verwenden, die für EF 5, 6 oder Core verfügbar sind. Diese Bibliotheken sind sehr leistungsfähig, wenn Sie löschen oder aktualisieren müssen, und sie verwenden LINQ. Beispiel für das Löschen ( Quelle plus ):

ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();

oder ( Quelle erweitert )

context.Users.Where(u => u.FirstName == "firstname") .Delete();

Diese verwenden native SQL-Anweisungen, so dass die Leistung hervorragend ist.

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