2012-09-07 15 views
16

Sto lavorando su un sistema che utilizza Entityframework e sono stato per più di 12 mesi ora, e il progetto è andato bene, fino a ieri, dove ora ho uno strano errore che non ho idea del perché capita. sto facendo nulla di diverso da quello che ho fatto prima, ma una volta mi carico l'entità in questione e cercare di accedere a qualsiasi entità figlio ottengo il seguente errore:EntityFramework - Errore proxy entità

The entity wrapper stored in the proxy does not reference the same proxy 

Qualcuno può far luce su ciò che questo in realtà significa e cosa potrebbe causare questo?

Mostrare il mio codice non aiuta molto.

Ecco una versione semplificata del codice:

var quote = new QuoteHelper().GetById(orderId); 
var updatedQuotes = new Provider().GetExportQuotes(quote.DeparturePoint.Id,quote.DestinationPoint); 

L'errore si verifica quando si accede correttamente DeparturePoint e DestinationPoint ma carichi citazione, e tutte le proprietà vengono caricati.

L'entità citazione sembra un po 'come questo:

public class Quote : BaseQuote, ICloneable 
{ 
    public Guid DeparturePointId { get; set; } 
    public virtual LocationPoint DeparturePoint{ get; set; } 

    public Guid DestinationPointId { get; set; } 
    public virtual LocationPoint DestinationPoint{ get; set; } 
} 

risposta

32

Questo è accaduto anche a me quando ho cercato di implementare ICloneable sul mio soggetto e clonato utilizzando MemberwiseClone. Ha funzionato benissimo quando stavo usando le entità che ho istanziato da me stesso. Tuttavia, quando ho usato questo per clonare un'entità che era stata caricata usando EF, ho ricevuto questo errore ogni volta che ho provato ad aggiungerlo a un DbSet (o in varie altre parti).

Dopo alcuni scavi, ho scoperto che quando cloni un'entità caricata con EF, stai clonando anche la classe proxy. Una delle cose che una classe proxy porta in giro è un riferimento al wrapper per l'entità data. Poiché una copia superficiale copia solo un riferimento al wrapper, all'improvviso ci sono due entità che hanno la stessa istanza wrapper.

A questo punto, EF ritiene che tu abbia creato o preso in prestito una classe proxy diversa per la tua entità che si presume sia per scopi di malizia e blocchi.

Modifica

Ecco un frammento che ho creato per ovviare a questo problema. Si noti che questo farà un buon lavoro nel copiare solo le proprietà EF, ma non è perfetto. Nota che dovrai modificarlo se hai dei campi privati ​​che devono essere copiati, ma ti viene l'idea.

/// <summary> 
    /// Makes a shallow copy of an entity object. This works much like a MemberwiseClone 
    /// but directly instantiates a new object and copies only properties that work with 
    /// EF and don't have the NotMappedAttribute. 
    /// </summary> 
    /// <typeparam name="TEntity">The entity type.</typeparam> 
    /// <param name="source">The source entity.</param> 
    public static TEntity ShallowCopyEntity<TEntity>(TEntity source) where TEntity : class, new() 
    { 

     // Get properties from EF that are read/write and not marked witht he NotMappedAttribute 
     var sourceProperties = typeof(TEntity) 
           .GetProperties() 
           .Where(p => p.CanRead && p.CanWrite && 
              p.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.NotMappedAttribute), true).Length == 0); 
     var newObj = new TEntity(); 

     foreach (var property in sourceProperties) 
     { 

      // Copy value 
      property.SetValue(newObj, property.GetValue(source, null), null); 

     } 

     return newObj; 

    } 
+1

Grazie, ho avuto un orribile metodo di clonazione e membro è sembrato come se la magia di cui avevo bisogno mi sembrasse che non fosse così. Grazie. – JamesStuddart

+0

MemberwiseClone è spesso la magia di cui hai bisogno, ma EF fa alcune cose uniche. A proposito, se trovi che questa soluzione non è sufficiente, ho anche sentito parlare di persone che usano [AutoMapper] (http://automapper.org/) per un economico meccanismo di clonazione. Non era destinato a questo, ma ciò non significa che non sia una soluzione perfettamente valida. –

+0

Grazie, ho fatto un pasticcio per risolvere il problema, ma quando avrò il tempo di tornare ad esso implementerò una delle soluzioni che hai dato.Grazie per l'intuizione, sembra che non ci sia molto in questo numero e spero che questo aiuti anche altre persone. – JamesStuddart

1

Sopra soluzione può verificarsi come errore "sono stati rilevati Modifiche in conflitto al ruolo x del rapporto y". Raggiunto quell'errore con l'uso di questo metodo;

public virtual TEntity DetachEntity(TEntity entityToDetach) 
    { 
     if (entityToDetach != null) 
      context.Entry(entityToDetach).State = EntityState.Detached; 
     context.SaveChanges(); 
     return entityToDetach; 
    } 

spero che funzionerà anche per te.

Problemi correlati