Est-il possible de vérifier si un objet est déjà attaché à un contexte de données dans Entity Framework?

.net entity-framework

Question

Le message d'erreur suivant s'affiche lorsque j'essaie d'attacher un objet déjà attaché à un contexte donné via context.AttachTo(...) :

Un objet avec la même clé existe déjà dans ObjectStateManager. ObjectStateManager ne peut pas suivre plusieurs objets avec la même clé.

Existe-t-il un moyen de réaliser quelque chose comme:

context.IsAttachedTo(...)

À votre santé!

Modifier:

La méthode d'extension décrite par Jason est proche, mais elle ne fonctionne pas dans mon cas.

J'essaie de travailler avec la méthode décrite dans la réponse à une autre question:

Comment supprimer une ou plusieurs lignes de ma table à l'aide de Linq to Entities * sans * récupérer les lignes en premier?

Mon code ressemble un peu à ceci:

var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();

Cela fonctionne bien, sauf lorsque je fais quelque chose d'autre pour cet utilisateur, que j'utilise la même méthode et que j'essaie d'attacher un objet User factice. Cela échoue car j'ai précédemment joint cet objet utilisateur factice. Comment puis-je vérifier cela?

Réponse acceptée

Voici ce que j'ai fini avec, qui fonctionne très bien:

public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
    where T : IEntityWithKey
{
    ObjectStateEntry entry;
    // Track whether we need to perform an attach
    bool attach = false;
    if (
        context.ObjectStateManager.TryGetObjectStateEntry
            (
                context.CreateEntityKey(entitySetName, entity),
                out entry
            )
        )
    {
        // Re-attach if necessary
        attach = entry.State == EntityState.Detached;
        // Get the discovered entity to the ref
        entity = (T)entry.Entity;
    }
    else
    {
        // Attach for the first time
        attach = true;
    }
    if (attach)
        context.AttachTo(entitySetName, entity);
}

Vous pouvez l'appeler comme suit:

User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);

Cela fonctionne très bien car c'est comme context.AttachTo(...) sauf que vous pouvez utiliser le truc d'identification que j'ai cité ci-dessus à chaque fois. Vous vous retrouvez avec l'objet précédemment attaché ou votre propre objet étant attaché. L'appel de CreateEntityKey sur le contexte permet de s'assurer qu'il est générique et qu'il fonctionne même avec des clés composites sans codage supplémentaire (car EF peut déjà le faire pour nous!).


Réponse populaire

Une approche plus simple consiste à:

 bool isDetached = context.Entry(user).State == EntityState.Detached;
 if (isDetached)
     context.Users.Attach(user);


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow