J'ai récemment travaillé avec Entity Framework 4 et je ne sais pas trop quand utiliser ObjectSet.Attach et ObjectSet.AddObject .
D'après ma compréhension:
- Utilisez "Joindre" lorsqu'une entité existe déjà dans le système
- Utilisez "AddObject" lors de la création d'une nouvelle entité
Donc, si je crée une nouvelle personne , je le fais.
var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();
Si je modifie une personne existante , je fais ceci:
var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();
Gardez à l'esprit qu'il s'agit d'un exemple très simple . En réalité, j'utilise Pure POCO (pas de génération de code), le modèle de référentiel (ne traite pas avec ctx.Persons) et Unit of Work (ne traite pas avec ctx.SaveChanges). Mais "sous les couvertures", ce qui précède est ce qui se passe dans ma mise en œuvre.
Maintenant, ma question - je n'ai pas encore trouvé de scénario dans lequel j'ai dû utiliser Attach .
Qu'est-ce que j'oublie ici? Quand devons-nous utiliser Attach?
ÉDITER
Juste pour clarifier, je cherche des exemples d'utilisation de Attach sur AddObject (ou vice-versa).
MODIFIER 2
La réponse ci-dessous est correcte (ce que j'ai accepté), mais j'ai pensé ajouter un autre exemple où Attach serait utile.
Dans mon exemple ci-dessus pour modifier une personne existante , deux requêtes sont en cours d'exécution.
Un pour récupérer la personne (.SingleOrDefault) et un autre pour effectuer la mise à jour (.SaveChanges).
Si (pour une raison quelconque), je savais déjà que "Joe Bloggs" existait dans le système, pourquoi faire une requête supplémentaire pour l'obtenir en premier? Je pourrais faire ceci:
var ctx = new MyEntities();
var existingPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.Attach(existingPerson);
ctx.SaveChanges();
Cela entraînera uniquement l'exécution d'une instruction UPDATE.
la source
Réponses:
ObjectContext.AddObject et ObjectSet.AddObject :
laméthode AddObject permet d'ajouter des objets nouvellement créés qui n'existent pas dans la base de données. L'entité recevra une EntityKey temporaire générée automatiquementet son EntityState sera défini sur Ajouté . Lorsque SaveChanges est appelé, il sera clair pour l'EF que cette entité doit être insérée dans la base de données.
ObjectContext.Attach et ObjectSet.Attach :
D'autre part, Attach est utilisé pour les entités qui existent déjàdans la base de données. Plutôt que de définir EntityState sur Added, Attach aboutit à unEntityState inchangé , ce qui signifie qu'il n'a pas changé depuis qu'il a été attaché au contexte. Les objets que vous attachez sont supposés exister dans la base de données. Si vous modifiez les objets une fois qu'ils ont été attachés, lorsque vous appelez SaveChanges, la valeur de EntityKey est utilisée pour mettre à jour (ou supprimer) la ligne appropriée en recherchant son ID correspondant dans la table db.
De plus, à l'aide de la méthode Attach, vous pouvez définir des relations entre des entités qui existent déjà dans ObjectContext mais qui ontpas été connecté automatiquement. Fondamentalement, l'objectif principal de Attach est de connecter des entités qui sont déjà attachées à ObjectContext et qui ne sont pas nouvelles, vous ne pouvez donc pas utiliser Attach pour attacher des entités dont EntityState est ajouté. Vous devez utiliser Add () dans ce cas.
Par exemple, supposons que votre entité Person possède une propriété de navigation nommée Addresses qui est une collection d'entités Address . Supposons que vous ayez lu les deux objets à partir du contexte, mais qu'ils ne sont pas liés les uns aux autres et que vous souhaitez que ce soit le cas:
la source
C'est une réponse tardive, mais cela pourrait aider d'autres personnes qui le trouvent.
Fondamentalement, une entité "déconnectée" peut se produire lorsque vous manipulez une entité en dehors de la portée "using".
Si vous entrez une autre portée "using", alors la variable "e" sera déconnectée car elle appartient à la portée "using" précédente et puisque la portée "using" précédente est détruite, alors "e" est déconnecté.
C'est comme ça que je le comprends.
la source
Ceci est une citation de Programming Entity Framework: DbContext
la source
Qu'en est-il de se référer uniquement à la clé primaire au lieu de l'attacher?
c'est à dire:
la source