Je supprime plusieurs éléments d'une table à l'aide d'Entity Framework. Il n'y a pas d'objet clé étrangère / parent, je ne peux donc pas gérer cela avec OnDeleteCascade.
En ce moment je fais ça:
var widgets = context.Widgets
.Where(w => w.WidgetId == widgetId);
foreach (Widget widget in widgets)
{
context.Widgets.DeleteObject(widget);
}
context.SaveChanges();
Cela fonctionne mais le foreach me dérange. J'utilise EF4 mais je ne veux pas exécuter SQL. Je veux juste m'assurer de ne rien manquer - c'est aussi bon que possible, non? Je peux l'abstraire avec une méthode d'extension ou un assistant, mais quelque part, nous allons toujours faire un foreach, non?
entity-framework
Jon Galloway
la source
la source
Réponses:
Si vous ne voulez pas exécuter SQL directement en appelant DeleteObject dans une boucle, c'est le mieux que vous puissiez faire aujourd'hui.
Cependant, vous pouvez exécuter SQL et toujours le rendre complètement général via une méthode d'extension, en utilisant l'approche que je décris ici .
Bien que cette réponse soit pour 3.5. Pour 4.0, j'utiliserais probablement la nouvelle API ExecuteStoreCommand sous le capot, au lieu de passer à StoreConnection.
la source
EntityFramework 6 a rendu cela un peu plus facile avec
.RemoveRange()
.Exemple:
la source
Eh bien, oui, sauf que vous pouvez en faire une doublure:
la source
la source
WHERE IN ({0})
, et le deuxième argument devrait êtreString.Join(",", idList)
.EntityFramework.Extended
String.Join
, vous devrez peut-être utiliserstring.Format
et transmettre la chaîne SQL déjà formée à la commande. Tant que votre liste n'a que des entiers, il n'y a pas de risque d'attaque par injection. Vérifiez cette question: comment puis-je passer un tableau à une commande d'exécution de magasin?Je sais qu'il est assez tard mais si quelqu'un a besoin d'une solution simple, le truc sympa est que vous pouvez également ajouter la clause where avec:
Remarque: vient d'être testé avec MSSQL2008.
Mettre à jour:
La solution ci-dessus ne fonctionnera pas lorsque EF génère une instruction sql avec des paramètres , alors voici la mise à jour pour EF5 :
Il nécessite un peu de réflexion mais fonctionne bien.
la source
Pour toute personne utilisant EF5, la bibliothèque d'extensions suivante peut être utilisée: https://github.com/loresoft/EntityFramework.Extended
la source
Delete()
fonction dans mes entités dans EF6.context.Widgets.Where(w => w.WidgetId == widgetId).Delete();
est la manière la plus récente avec EntityFramework.ExtendedIl semble toujours fou de devoir retirer quoi que ce soit du serveur pour le supprimer, mais au moins récupérer uniquement les identifiants est beaucoup plus simple que de retirer les entités complètes:
la source
Widget
objets de stub n'ont qu'uneId
propriété initialisée . La solution consiste à utilisercontext.Configuration.ValidateOnSaveEnabled = false
(au moins dans EF6). Cela désactive la propre validation d'Entity Framework, mais effectue bien sûr la propre validation de la base de données.delete
avec une solution de contournement similaire pourupdate
les entités sans les charger.EF 6.1
Usage:
la source
Pour EF 4.1,
la source
Vous pouvez utiliser des bibliothèques d'extensions pour cela, comme EntityFramework.Extended ou Z.EntityFramework.Plus.EF6, elles sont disponibles pour EF 5, 6 ou Core. Ces bibliothèques ont d'excellentes performances lorsque vous devez supprimer ou mettre à jour et qu'elles utilisent LINQ. Exemple de suppression ( source plus ):
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();
ou ( source étendue )
context.Users.Where(u => u.FirstName == "firstname") .Delete();
Ceux-ci utilisent des instructions SQL natives, donc les performances sont excellentes.
la source
La façon la plus rapide de supprimer consiste à utiliser une procédure stockée. Je préfère les procédures stockées dans un projet de base de données au SQL dynamique car les renommages seront traités correctement et comportent des erreurs de compilation. Dynamic SQL peut faire référence à des tables qui ont été supprimées / renommées, provoquant des erreurs d'exécution.
Dans cet exemple, j'ai deux tables List et ListItems. J'ai besoin d'un moyen rapide pour supprimer tous les ListItems d'une liste donnée.
Maintenant, la partie intéressante de la suppression des éléments et de la mise à jour du framework Entity à l'aide d'une extension.
Le code principal peut maintenant l'utiliser comme
la source
Si vous souhaitez supprimer toutes les lignes d'une table, vous pouvez exécuter la commande sql
TRUNCATE TABLE (Transact-SQL) Supprime toutes les lignes d'une table sans enregistrer les suppressions de lignes individuelles. TRUNCATE TABLE est similaire à l'instruction DELETE sans clause WHERE; cependant, TRUNCATE TABLE est plus rapide et utilise moins de ressources système et de journal des transactions.
la source
truncate table
sur des tables référencées par une contrainte FOREIGN KEY. (Vous pouvez tronquer une table qui a une clé étrangère qui se référence elle-même.). Documentation MSDNUUHHIVS
est un moyen très élégant et rapide pour la suppression par lots, mais il doit être utilisé avec précaution:context.SaveChanges()
Ces problèmes peuvent être contournés en prenant le contrôle de la transaction. Le code suivant illustre comment supprimer par lot et insérer en bloc de manière transactionnelle:
la source
Entity Framework Core
Résumé :
Remarques :
la source
Vous pouvez exécuter des requêtes SQL directement comme suit:
Pour certains, nous pouvons utiliser
la source
Vous pouvez également utiliser la méthode DeleteAllOnSubmit () en lui passant vos résultats dans une liste générique plutôt que dans var. De cette façon, votre foreach se réduit à une seule ligne de code:
Cependant, il utilise probablement une boucle en interne.
la source
var
.La réponse de Thanh a fonctionné le mieux pour moi. Supprimé tous mes enregistrements en un seul voyage sur le serveur. J'ai eu du mal à appeler la méthode d'extension, alors j'ai pensé partager la mienne (EF 6):
J'ai ajouté la méthode d'extension à une classe d'assistance dans mon projet MVC et j'ai changé le nom en "RemoveWhere". J'injecte un dbContext dans mes contrôleurs, mais vous pouvez également faire un
using
.Cela a généré une seule instruction de suppression pour le groupe.
la source
EF 6. =>
la source
Meilleur :
in EF6 => .RemoveRange()
Exemple:
la source
Voir la réponse «morceau de code préféré» qui fonctionne
Voici comment je l'ai utilisé:
la source
Dans EF 6.2, cela fonctionne parfaitement, en envoyant la suppression directement à la base de données sans charger d'abord les entités:
Avec un prédicat fixe, c'est assez simple:
Et si vous avez besoin d'un prédicat dynamique, jetez un œil à LINQKit (package Nuget disponible), quelque chose comme ça fonctionne bien dans mon cas:
la source
Z.EntityFramework.Plus
ou quelque chose de similaire? ( entityframework.net/batch-delete )Delete()
méthode est intrinsèquement inexistante).