Wie kann ich mit Entity Framework schnell alle Zeilen in der Tabelle entfernen?
Ich benutze derzeit:
var rows = from o in dataDb.Table
select o;
foreach (var row in rows)
{
dataDb.Table.Remove(row);
}
dataDb.SaveChanges();
Die Ausführung dauert jedoch lange.
Gibt es Alternativen?
c#
sql
linq
entity-framework
Zhenia
quelle
quelle
TRUNCATE
Adepten Sorgen um Fremdschlüsseleinschränkungen macht.[TableName]
, ist sie nicht portierbar.Antworten:
Für diejenigen, die dies googeln und wie ich hier gelandet sind, ist dies derzeit in EF5 und EF6 der Fall:
Angenommen, der Kontext ist a
System.Data.Entity.DbContext
quelle
[
Escapezeichen hier zwar spezifisch für SQL Server sind, derTRUNCATE
Befehl jedoch nicht - er ist Teil von ANSI SQL und funktioniert daher in den meisten SQL-Dialekten (jedoch nicht in SQLite).Warnung: Das Folgende ist nur für kleine Tabellen geeignet (denken Sie an <1000 Zeilen).
Hier ist eine Lösung, die das Entity Framework (nicht SQL) zum Löschen der Zeilen verwendet, sodass sie nicht SQL Engine (R / DBM) -spezifisch ist.
Dies setzt voraus, dass Sie dies zum Testen oder in einer ähnlichen Situation tun. Entweder
Rufen Sie einfach an:
Unter der Annahme dieses Kontextes:
Für aufgeräumten Code können Sie die folgende Erweiterungsmethode deklarieren:
Dann wird das Obige:
Ich habe diesen Ansatz kürzlich verwendet, um meine Testdatenbank für jeden Testfalllauf zu bereinigen (es ist offensichtlich schneller, als die Datenbank jedes Mal von Grund auf neu zu erstellen, obwohl ich die Form der generierten Löschbefehle nicht überprüft habe).
Warum kann es langsam sein?
Wenn Sie also mit einer großen Datenmenge arbeiten, beenden Sie den SQL Server-Prozess (er verbraucht den gesamten Speicher) und das Gleiche für den IIS-Prozess, da EF alle Daten auf die gleiche Weise wie SQL Server zwischenspeichert. Verwenden Sie diese nicht, wenn Ihre Tabelle ernsthafte Datenmengen enthält.
quelle
Die Verwendung des SQL-
TRUNCATE TABLE
Befehls ist am schnellsten, da er für die Tabelle und nicht für einzelne Zeilen ausgeführt wird.Angenommen, es
dataDb
ist einDbContext
(keinObjectContext
), können Sie es einpacken und die folgende Methode verwenden:quelle
TRUNCATE TABLE
zuDELETE FROM
quelle
oder
quelle
Delete
fürIQueryable
- ich vermute, Manish hat so etwas wie EntityFramework.Extended verwendet: github.com/loresoft/EntityFramework.Extended.Delete
war eine benutzerdefinierte Erweiterung und in der Hitze, die Antwort zuerst zu veröffentlichen, völlig vergessen, die Definition dieser benutzerdefinierten zu erwähnen.Delete
. :)Sie können das ohne Foreach tun
Dadurch werden alle Zeilen entfernt
quelle
Dadurch wird die Verwendung von SQL vermieden
quelle
Ich bin auf diese Frage gestoßen, als ich mich mit einem bestimmten Fall befassen musste: Vollständige Aktualisierung des Inhalts in einer "Blatt" -Tabelle (keine darauf zeigenden FKs). Dies beinhaltete das Entfernen aller Zeilen und das Einfügen neuer Zeileninformationen und sollte transaktional erfolgen (ich möchte nicht mit einer leeren Tabelle enden, wenn Einfügungen aus irgendeinem Grund fehlschlagen).
Ich habe das versucht
public static void Clear<T>(this DbSet<T> dbSet)
Ansatz , aber neue Zeilen werden nicht eingefügt. Ein weiterer Nachteil ist, dass der gesamte Prozess langsam ist, da die Zeilen einzeln gelöscht werden.Also habe ich auf
TRUNCATE
Annäherung umgestellt , da es viel schneller und auch ROLLBACKable ist . Es setzt auch die Identität zurück.Beispiel mit Repository-Muster:
Wie bereits erwähnt, kann diese Lösung natürlich nicht von Tabellen verwendet werden, auf die durch Fremdschlüssel verwiesen wird (TRUNCATE schlägt fehl).
quelle
Cannot truncate table because it is being referenced by a FOREIGN KEY constraint
), auch wenn sie leer sind. Daher müssen FKs gelöscht und neu erstellt werden, damit sieTRUNCATE
trotzdem verwendet werden können.wenn
Ursachen
Die Tabelle 'MyTable' kann nicht abgeschnitten werden, da sie durch eine FOREIGN KEY-Einschränkung referenziert wird.
Ich benutze das :
quelle
quelle
Wenn Sie Ihre gesamte Datenbank löschen möchten.
Aufgrund der Fremdschlüsseleinschränkungen ist es wichtig, in welcher Reihenfolge die Tabellen abgeschnitten werden. Dies ist eine Möglichkeit, diese Sequenz brutal zu erzwingen.
Verwendung:
Denken Sie daran, Ihren DbContext danach erneut zu installieren.
quelle
Das Folgende funktioniert in der SQLite-Datenbank (unter Verwendung von Entity Framework).
Es scheint, dass der schnellste Weg, alle DB-Tabellen zu löschen, die Verwendung von 'context.Database.ExecuteSqlCommand ("some SQL")' ist, wie einige der obigen Kommentare ebenfalls hervorheben. Hier werde ich zeigen, wie man auch die 'Index'-Anzahl von Tabellen zurücksetzt.
Ein wichtiger Punkt ist, dass Sie, wenn Sie Fremdschlüssel in Ihren Tabellen verwenden, zuerst die untergeordnete Tabelle vor der übergeordneten Tabelle löschen müssen. Daher ist die Reihenfolge (Hierarchie) der Tabellen während des Löschens wichtig, da sonst eine SQLite-Ausnahme auftreten kann.
Hinweis: var context = new YourContext ()
quelle
Dies funktioniert ordnungsgemäß in EF 5:
quelle
In EFCore (Version, die ich verwende, ist 3.1) können Sie Folgendes verwenden, um alle Zeilen zu entfernen:
quelle
Löschen Sie alle Datensätze. Setzen Sie den Primärindex nicht wie "Abschneiden" zurück.
quelle
In meinem Code hatte ich keinen wirklich guten Zugriff auf das Datenbankobjekt, daher können Sie dies auf dem DbSet tun, wo Sie auch jede Art von SQL verwenden dürfen. Es wird so enden:
quelle
Wenn MVC, können Sie:
quelle
Stellen Sie sicher, dass beim Löschen des übergeordneten Elements alle untergeordneten Elemente beim Löschen kaskadiert werden. Oder Kinder haben einen nullbaren Fremdschlüssel.
quelle
quelle