Quelqu'un a-t-il des suggestions sur la manière la plus efficace d'implémenter la logique «mise à jour de la ligne s'il existe, sinon insérer» à l'aide d'Entity Framework?
c#
entity-framework
Jonathan Wood
la source
la source
Réponses:
Si vous travaillez avec un objet attaché (objet chargé à partir de la même instance du contexte), vous pouvez simplement utiliser:
Si vous pouvez utiliser des connaissances sur la clé de l'objet, vous pouvez utiliser quelque chose comme ceci:
Si vous ne pouvez pas décider de l'existence de l'objet par son identifiant, vous devez exécuter une requête de recherche:
la source
using
bloc. Est-il acceptable de laisser le contexte en mémoire pendant un moment? Par exemple, pendant la durée de vie d'un formulaire Windows? J'essaie normalement de nettoyer les objets de base de données pour assurer une charge minimale sur la base de données. N'y a-t-il aucun problème à attendre de détruire mon contexte EF?Depuis Entity Framework 4.3, il existe une
AddOrUpdate
méthode dans l'espace de nomsSystem.Data.Entity.Migrations
:qui par le doc :
Pour répondre au commentaire de @ Smashing1978 , je vais coller les parties pertinentes du lien fourni par @Colin
Cela dit, j'ai une situation dans laquelle je tire des données d'un service externe et j'insère ou mets à jour des valeurs existantes par clé primaire (et mes données locales pour les consommateurs sont en lecture seule) - j'utilise
AddOrUpdate
en production depuis plus de 6 mois maintenant et donc loin aucun problème.la source
La magie se produit lors de l'appel
SaveChanges()
et dépend du courantEntityState
. Si l'entité a unEntityState.Added
, elle sera ajoutée à la base de données, si elle en a unEntityState.Modified
, elle sera mise à jour dans la base de données. Vous pouvez donc implémenter uneInsertOrUpdate()
méthode comme suit:En savoir plus sur EntityState
Si vous ne pouvez pas vérifier
Id = 0
s'il s'agit d'une nouvelle entité ou non, vérifiez la réponse de Ladislav Mrnka .la source
Si vous savez que vous utilisez le même contexte et que vous ne détachez aucune entité, vous pouvez créer une version générique comme celle-ci:
db
peut bien sûr être un champ de classe, ou la méthode peut être rendue statique et une extension, mais ce sont les bases.la source
La réponse de Ladislav était proche mais j'ai dû faire quelques modifications pour que cela fonctionne dans EF6 (base de données d'abord). J'ai étendu mon contexte de données avec ma méthode on AddOrUpdate et jusqu'à présent, cela semble bien fonctionner avec les objets détachés:
la source
À mon avis, il vaut la peine de dire qu'avec le tout nouveau EntityGraphOperations pour Entity Framework Code First, vous pouvez vous éviter d'écrire des codes répétitifs pour définir les états de toutes les entités du graphique. Je suis l'auteur de ce produit. Et je l'ai publié dans le github , code-project ( comprend une démonstration étape par étape et un exemple de projet est prêt à être téléchargé) et nuget .
Il définira automatiquement l'état des entités sur
Added
ouModified
. Et vous choisirez manuellement quelles entités doivent être supprimées si elles n'existent plus.L'exemple:
Disons que j'ai un
Person
objet.Person
pourrait avoir plusieurs téléphones, un document et pourrait avoir un conjoint.Je souhaite déterminer l'état de toutes les entités incluses dans le graphique.
De plus, comme vous le savez, les propriétés de clé uniques pourraient jouer un rôle lors de la définition de l'état de l'entité Phone. Pour ces fins spéciales, nous avons la
ExtendedEntityTypeConfiguration<>
classe, qui hérite deEntityTypeConfiguration<>
. Si nous voulons utiliser de telles configurations spéciales, nous devons hériter de nos classes de mappageExtendedEntityTypeConfiguration<>
plutôt que deEntityTypeConfiguration<>
. Par exemple:C'est tout.
la source
Insérer autre mettre à jour les deux
la source
Vérifiez la ligne existante avec Any.
la source
Alternative pour la réponse @LadislavMrnka. Cela vaut pour Entity Framework 6.2.0.
Si vous avez un
DbSet
élément spécifique et un élément qui doit être mis à jour ou créé:Cependant, cela peut également être utilisé pour un générique
DbSet
avec une seule clé primaire ou une clé primaire composite.la source
Corrigée
la source