Jak mogę szybko usunąć wszystkie wiersze w tabeli za pomocą Entity Framework?
Obecnie używam:
var rows = from o in dataDb.Table
select o;
foreach (var row in rows)
{
dataDb.Table.Remove(row);
}
dataDb.SaveChanges();
Wykonanie zajmuje jednak dużo czasu.
Czy są jakieś alternatywy?
c#
sql
linq
entity-framework
Zenia
źródło
źródło
TRUNCATE
adeptów nie martwi się ograniczeniami klucza obcego.[TableName]
, nie jest przenośna.Odpowiedzi:
Dla tych, którzy googlują i skończyli tutaj, jak ja, tak właśnie robisz w EF5 i EF6:
Zakładając, że kontekst to
System.Data.Entity.DbContext
źródło
[
tutaj znaki ucieczki są specyficzne dla SQL Server,TRUNCATE
polecenie nie jest - jest częścią ANSI SQL i dlatego będzie działać w większości dialektów SQL (choć nie SQLite).Ostrzeżenie: Poniższe informacje są odpowiednie tylko dla małych tabel (pomyśl <1000 wierszy)
Oto rozwiązanie, które używa struktury encji (nie SQL) do usuwania wierszy, więc nie jest ono specyficzne dla SQL Engine (R / DBM).
Zakłada się, że robisz to w celu przetestowania lub w podobnej sytuacji. Zarówno
Po prostu zadzwoń:
Zakładając ten kontekst:
W przypadku kodu uporządkowanego można zadeklarować następującą metodę rozszerzenia:
Następnie powyższe staje się:
Ostatnio zastosowałem to podejście do czyszczenia mojej testowej bazy danych dla każdego uruchomienia zestawu testów (jest to oczywiście szybsze niż za każdym razem odtwarzanie DB od zera, chociaż nie sprawdzałem formy wygenerowanych poleceń usuwania).
Dlaczego może być powolny?
Więc jeśli pracujesz z poważną ilością danych, zabijesz proces serwera SQL (zajmie to całą pamięć) i to samo dla procesu IIS, ponieważ EF będzie buforował wszystkie dane w taki sam sposób jak serwer SQL. Nie używaj tego, jeśli twoja tabela zawiera poważne ilości danych.
źródło
Korzystanie z
TRUNCATE TABLE
polecenia SQL będzie najszybsze, ponieważ działa on na tabeli, a nie na poszczególnych wierszach.Zakładając, że
dataDb
jestDbContext
(nie anObjectContext
), możesz go owinąć i użyć następującej metody:źródło
TRUNCATE TABLE
naDELETE FROM
źródło
lub
źródło
Delete
naIQueryable
- Zgaduję Manish używałem czegoś takiego EntityFramework.Extended: github.com/loresoft/EntityFramework.Extended.Delete
było niestandardowe rozszerzenie i w ogniu pierwszego opublikowania odpowiedzi całkowicie zapomniałem wspomnieć o definicji tego zwyczaju.Delete
. :)Możesz to zrobić bez Foreach
Spowoduje to usunięcie wszystkich wierszy
źródło
Pozwala to uniknąć korzystania z SQL
źródło
Natknąłem się na to pytanie, kiedy miałem do czynienia z konkretnym przypadkiem: pełną aktualizacją treści w tabeli „liści” (bez FK wskazujących na to). Obejmowało to usunięcie wszystkich wierszy i umieszczenie nowych informacji o wierszach i powinno to zostać wykonane transakcyjnie (nie chcę skończyć z pustą tabelą, jeśli wstawianie nie powiedzie się z jakiegokolwiek powodu).
Próbowałem
public static void Clear<T>(this DbSet<T> dbSet)
podejścia, ale nowe wiersze nie są wstawiane. Inną wadą jest to, że cały proces jest powolny, ponieważ wiersze są usuwane jeden po drugim.Zmieniłem więc
TRUNCATE
podejście, ponieważ jest ono znacznie szybsze i można je również ODWRÓCIĆ . Resetuje także tożsamość.Przykład użycia wzorca repozytorium:
Oczywiście, jak już wspomniano, z tego rozwiązania nie mogą korzystać tabele, do których odwołują się klucze obce (TRUNCATE kończy się niepowodzeniem).
źródło
Cannot truncate table because it is being referenced by a FOREIGN KEY constraint
), nawet jeśli są puste, więc FK muszą zostać usunięte i ponownie utworzone , aby móc z nich skorzystaćTRUNCATE
.Jeśli
przyczyny
Nie można obciąć tabeli „MyTable”, ponieważ odwołuje się do niej klucz OBCY.
Używam tego :
źródło
źródło
Jeśli chcesz wyczyścić całą bazę danych.
Z powodu ograniczeń klucza obcego ważne jest, w jakiej kolejności tabele są obcinane. Jest to sposób na brutalne użycie tej sekwencji.
stosowanie:
pamiętaj, aby po tym przywrócić DbContext.
źródło
Poniższe działa na bazie danych SQLite (przy użyciu Entity Framework)
Wydaje się, że najszybszym sposobem na wyczyszczenie wszystkich tabel db jest użycie „context.Database.ExecuteSqlCommand („ some SQL ”)”, jak również podkreślono niektóre komentarze powyżej. Tutaj pokażę, jak zresetować liczbę „indeksów” tabel.
Ważną kwestią jest to, że jeśli używasz kluczy obcych w swoich tabelach, musisz najpierw usunąć tabelę podrzędną przed tabelą nadrzędną, więc kolejność (hierarchia) tabel podczas usuwania jest ważna, w przeciwnym razie może wystąpić wyjątek SQLite.
Uwaga: var context = new YourContext ()
źródło
Działa to poprawnie w EF 5:
źródło
W EFCore (wersja, której używam to 3.1) możesz użyć następujących elementów, aby usunąć wszystkie wiersze -
źródło
Usuń wszystkie rekordy. Nie resetuj głównego indeksu, np. „Obcinaj”.
źródło
W moim kodzie tak naprawdę nie miałem ładnego dostępu do obiektu Database, więc możesz to zrobić na DbSet, gdzie możesz także używać dowolnego rodzaju sql. Skończy się to tak:
źródło
Jeśli MVC, możesz:
źródło
Upewnij się, że kiedy próbujesz usunąć rodzica, wszystkie dzieci będą kaskadowo przy usuwaniu. Lub dzieci mają zerowy klucz obcy.
źródło
źródło