Comment puis-je supprimer rapidement toutes les lignes du tableau à l'aide d'Entity Framework?
J'utilise actuellement:
var rows = from o in dataDb.Table
select o;
foreach (var row in rows)
{
dataDb.Table.Remove(row);
}
dataDb.SaveChanges();
Cependant, son exécution est longue.
Y a-t-il des alternatives?
c#
sql
linq
entity-framework
Zhenia
la source
la source
TRUNCATE
adeptes ne s'inquiète des contraintes liées aux clés étrangères.[TableName]
, elle n'est pas portable.Réponses:
Pour ceux qui googlent cela et se retrouvent ici comme moi, c'est comme ça que vous le faites actuellement dans EF5 et EF6:
En supposant que le contexte est un
System.Data.Entity.DbContext
la source
[
échappements ici soient spécifiques à SQL Server, laTRUNCATE
commande ne l'est pas - elle fait partie de ANSI SQL et fonctionnera donc dans la plupart des dialectes SQL (mais pas SQLite).Avertissement: ce qui suit ne convient que pour les petites tables (pensez <1000 lignes)
Voici une solution qui utilise le framework d'entité (pas SQL) pour supprimer les lignes, elle n'est donc pas spécifique à SQL Engine (R / DBM).
Cela suppose que vous effectuez cette opération pour des tests ou une situation similaire. Soit
Appelez simplement:
En supposant ce contexte:
Pour un code plus ordonné, vous pouvez déclarer la méthode d'extension suivante:
Ensuite, ce qui précède devient:
J'ai récemment utilisé cette approche pour nettoyer ma base de données de test pour chaque exécution de testcase (c'est évidemment plus rapide que de recréer la base de données à chaque fois, bien que je n'ai pas vérifié la forme des commandes de suppression qui ont été générées).
Pourquoi cela peut-il être lent?
Donc, si vous travaillez avec une quantité importante de données, vous tuerez le processus du serveur SQL (il consommera toute la mémoire) et la même chose pour le processus IIS car EF mettra en cache toutes les données de la même manière que le serveur SQL. N'utilisez pas celui-ci si votre table contient une quantité importante de données.
la source
L'utilisation de la
TRUNCATE TABLE
commande SQL sera la plus rapide car elle opère sur la table et non sur des lignes individuelles.En supposant que
dataDb
c'est unDbContext
(pas unObjectContext
), vous pouvez le boucler et utiliser la méthode comme ceci:la source
TRUNCATE TABLE
enDELETE FROM
la source
ou
la source
Delete
surIQueryable
- Je devine que Manish utilisait quelque chose comme EntityFramework.Extended: github.com/loresoft/EntityFramework.Extended.Delete
s'agissait d'une extension personnalisée et dans le feu de la publication de la première réponse, j'ai totalement oublié de mentionner la définition de cette coutume.Delete
. :)Vous pouvez le faire sans Foreach
Cela supprimera toutes les lignes
la source
Cela évite d'utiliser n'importe quel sql
la source
Je suis tombé sur cette question quand j'ai dû faire face à un cas particulier: la mise à jour complète du contenu dans une table "feuille" (pas de FK pointant dessus). Cela impliquait de supprimer toutes les lignes et de mettre de nouvelles informations sur les lignes et cela devrait être fait de manière transactionnelle (je ne veux pas me retrouver avec une table vide, si les insertions échouent pour une raison quelconque).
J'ai essayé le
public static void Clear<T>(this DbSet<T> dbSet)
approche, mais de nouvelles lignes ne sont pas insérées. Un autre inconvénient est que l'ensemble du processus est lent, car les lignes sont supprimées une par une.Je suis donc passé à l'
TRUNCATE
approche, car il est beaucoup plus rapide et il est également ROLLBACKable . Il réinitialise également l'identité.Exemple utilisant un modèle de référentiel:
Bien sûr, comme déjà mentionné, cette solution ne peut pas être utilisée par des tables référencées par des clés étrangères (TRUNCATE échoue).
la source
Cannot truncate table because it is being referenced by a FOREIGN KEY constraint
), même si elles sont vides, donc les FK doivent être supprimés et recréés pour pouvoir être utilisés deTRUNCATE
toute façon.si
les causes
Impossible de tronquer la table 'MyTable' car elle est référencée par une contrainte FOREIGN KEY.
J'utilise ceci:
la source
la source
Si vous souhaitez effacer l'intégralité de votre base de données.
En raison des contraintes de clé étrangère, il importe de savoir dans quelle séquence les tables sont tronquées. C'est un moyen de renforcer brutalement cette séquence.
usage:
n'oubliez pas de réactiver votre DbContext après cela.
la source
Les travaux suivants sur la base de données SQLite (en utilisant Entity Framework)
Il semble que le moyen le plus rapide d'effacer toutes les tables de base de données utilise "context.Database.ExecuteSqlCommand (" certains SQL ")", comme certains commentaires ci-dessus l'ont également souligné. Ici, je vais montrer comment réinitialiser le nombre d'index des tables aussi.
Un point important est que si vous utilisez des clés étrangères dans vos tables, vous devez d'abord supprimer la table enfant avant la table parent, de sorte que la séquence (hiérarchie) des tables pendant la suppression est importante, sinon une exception SQLite peut se produire.
Remarque: var context = new YourContext ()
la source
Cela fonctionne correctement dans EF 5:
la source
Dans EFCore (la version que j'utilise est 3.1), vous pouvez utiliser ce qui suit pour supprimer toutes les lignes -
la source
Supprimez tous les enregistrements. Ne réinitialisez pas l'index primaire comme "tronquer".
la source
Dans mon code, je n'avais pas vraiment accès à l'objet Database, vous pouvez donc le faire sur le DbSet où vous pouvez également utiliser n'importe quel type de SQL. Cela se terminera en quelque sorte comme ceci:
la source
Si MVC, vous pouvez faire:
la source
Assurez-vous que lorsque vous essayez de supprimer le parent, tous les enfants seront mis en cascade lors de la suppression. Ou les enfants ont une clé étrangère nullable.
la source
la source