Entity Framework Code First – Aucune méthode Detach () sur DbContext

Je me demande pourquoi il n’y a pas de méthode Detach sur l’object DbContext comme pour ObjectContext. Je ne peux que supposer que cette omission était intentionnelle, mais j’ai du mal à comprendre pourquoi. Je dois pouvoir détacher et rattacher des entités (pour mettre dans le cache dans un projet ASP.NET, par exemple). Cependant, comme je ne peux pas détacher une entité, lorsque j’essaie d’attacher une entité associée à un contexte précédent, j’obtiens l’exception “Un object entité ne peut pas être référencé par plusieurs instances d’IEntityChangeTracker”.

Quelle est la guidance ici? Est-ce que je manque quelque chose?

Pour les personnes qui pourraient trébucher sur cette question, à partir de CTP5, vous devez maintenant écrire

((IObjectContextAdapter)context).ObjectContext 

pour accéder à ObjectContext.

DbContext utilise un object ObjectContext en interne et l’équipe EF la met à disposition en tant que propriété protégée au cas où vous auriez besoin de passer à l’API de niveau inférieur et que cela semble être le cas ici, vous pouvez donc utiliser ou exposer les fonctionnalités requirejses DbContext:

 public class YourContext : DbContext { public void Detach(object entity) { ObjectContext.Detach(entity); } } 

Ensuite, vous pouvez appeler cette méthode depuis votre contrôleur pour détacher une entité.

Alternativement, vous pouvez le changer pour avoir même une API plus riche:

 public class YourContext : DbContext { public void ChangeObjectState(object entity, EntityState entityState) { ObjectContext.ObjectStateManager.ChangeObjectState(entity, entityState); } } 

Voici à quoi ressemble DbContext à partir des métadonnées:

 public class DbContext : IDisposable { protected System.Data.Objects.ObjectContext ObjectContext { get; } ... } 

EF: CF 4.1 RC1 et EF: CF 4.1 RTW ont la même implémentation explicite IObjectContextAdapter:

 public static class DbContextExtensions { public static void Detach(this System.Data.Entity.DbContext context, object entity) { ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.Detach(entity); } } 

Microsoft a décidé que “Detach est une technologie trop avancée et devrait être cachée”. IMHO l’homme qui a inventé cela devrait être tiré – parce que si vous ajoutez une nouvelle entité, il est difficile de simplement le supprimer sans engager des modifications à la firebase database (vous pouvez manipuler avec DbEntityEntry mais c’est une autre histoire).

Modifier 4 ans plus tard:

Avec EF6 (j’ai en quelque sorte ignoré EF5 :)) vous n’avez plus besoin de detach() , car supprimer l’entrée nouvellement ajoutée ne génère pas de delete from [table] where [Id] = 0 comme dans EF4 – vous pouvez simplement appeler mySet.Remove(myFreshlyCreatedAndAddedEntity) et tout ira bien.

J’étends généralement la classe de base (hérite de DbContext) avec la propriété:

 public class MyDbContext : DbContext { public ObjectContext ThisObjectContext { get { return ((IObjectContextAdapter)this).ObjectContext; } } } 

plus tard, vous pouvez utiliser cette propriété pour une variété de choses utiles … comme Detach 🙂