67 votes

Quel est le moyen le plus raisonnable de déterminer si une entité est liée à dbContext ou non?

quand j'essaie d'attacher une entité au contexte, je reçois une exception

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

C'est le comportement attendu.

Mais j'aimerais savoir comment ObjectStateManager le sait? Je voudrais faire ce chèque par moi-même avant

96voto

Ladislav Mrnka Points 218632

Si vous utilisez l'API DbContext (vous avez mentionné ef-code-first), vous pouvez simplement utiliser:

 context.YourEntities.Local.Any(e => e.Id == id);
 

ou plus complexe

 context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id);
 

Dans le cas de l'API ObjectContext, vous pouvez utiliser:

 context.ObjectStateManager.GetObjectStateEntires(~EntityState.Detached)
                          .Where(e => !e.IsRelationship)
                          .Select(e => e.Entity)
                          .OfType<YourEntity>()
                          .Any(x => x.Id == id);
 

13voto

David Sherret Points 3205

Voici une méthode d'extension pour extraire l'objet du contexte sans avoir à se demander s'il est déjà attaché:

 public static T AttachOrGetLocal<T>(this DbSet<T> collection, Func<T, bool> searchQuery, T addItem) where T : class
{
    T existsResult = collection.Local.FirstOrDefault(searchQuery);

    if (existsResult == null)
    {
        collection.Attach(addItem);
        return addItem;
    }
    else
    {
        return existsResult;
    }
}
 

Il suffit d'appeler:

 UserProfile user = dbContext.UserProfiles.AttachOrGetLocal<UserProfile>(u => u.UserId == userId, new UserProfile { UserId = userId });
 

5voto

Kaido Points 1305

vérifier

 entity.EntityState == System.Data.EntityState.Detached
 

avant de joindre

2voto

Dubbs777 Points 6

Notez que si le suivi des modifications est désactivé sur votre contexte, de demander l' ObjectStateManager ou ChangeTracker pourrait revenir que l'objet n'est pas dans l' ObjectContext cas si elle est en fait déjà là. Par conséquent, si vous essayez de joindre un tel objet, il déclenche une exception.

context.Set<T>.Local.Any(e => e.Id == id);

les œuvres de l'événement si le suivi des modifications est désactivé.

si vous ne connaissez pas le type de l'objet, il y a diverses approche, vous pouvez soit définir une méthode utilisant la réflexion ou à d'autres techniques comme celui-ci int GetIdOf(object entity){...}

Ou vous pouvez définir une interface utilisée par vos classes comme

public interface IMyEntity
{
    int Id{get;set;}
}

et de l'utiliser de cette façon :

context.Set(e.GetType()).Local.Cast<IMyEntity>().Any(e => e.Id == id);

0voto

Bongo Sharp Points 1414

vous pouvez interroger le dbContext avec la méthode d'extension "Any":

 bool alreadyInDB = dbContext.Entity.Where(a=>a.ID==myEntity.id).Any();
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X