Entity framework MappingException: le type 'XXX a été mappé plus d'une fois

.net c# entity-framework

Question

J'utilise Entity Framework dans une application Web. ObjectContext est créé à la demande (à l'aide de HttpContext), voici le code:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString();
if (!HttpContext.Current.Items.Contains(ocKey))
{
    HttpContext.Current.Items.Add(ocKey, new ElevationEntityModel(EFConnectionString));
}
_eem = HttpContext.Current.Items[ocKey] as ElevationEntityModel;

Pas à chaque fois, mais parfois j'ai cette exception:

System.Data.MappingException n'a pas été traité par le code utilisateur. Message = Le type 'XXX' a été mappé plusieurs fois. Source = System.Data.Entity

Je suis absolument confus et je n'ai aucune idée de ce qui peut causer ce problème.

Quelqu'un peut-il m'aider?

Réponse acceptée

Cela ressemble à un problème de synchronisation. Une solution simple serait d'avoir un objet verrou partagé (dans votre classe):

private static object _lock = new object();

Alors votre code devient:

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString(); 

lock (_lock) {
    if (!HttpContext.Current.Items.Contains(ocKey)) 
    { 
          HttpContext.Current.Items.Add(ocKey, new ElevationEntityModel(EFConnectionString)); 
    } 
    _eem = HttpContext.Current.Items[ocKey] as ElevationEntityModel; 

}

Le bloc de verrouillage signifie en gros qu'une fois qu'un thread entre dans le bloc "lock", aucun autre thread ne peut accéder à ce bloc jusqu'à la fin du premier thread. Cela arrêtera le conflit entre la méthode "Contains" et la méthode "Add".

Remarque: si un autre élément de votre application accède à la collection Items dans HttpContext.Current, vous devrez également effectuer la synchronisation. Il est sage de créer une collection personnalisée, de l'ajouter à la collection Items et de synchroniser l'accès à celle-ci.


Réponse populaire

Cela est dû au fait que plusieurs processus sont en cours et que vous accédez au même ObjectContext sans synchroniser les threads au préalable ...



Related

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