2010-09-20 7 views
14

Ho una classe base DomainObject per tutti i miei oggetti business che sto utilizzando con NHibernate. Contiene la proprietà Id.Come si ottiene il tipo di entità su un oggetto che potrebbe essere un oggetto proxy NHibernate?

public abstract class DomainObject 
{ 
    public virtual int Id { get; private set; } 
} 

Vorrei scrivere un IEqualityComparer per confrontare i miei oggetti di dominio. Se due oggetti hanno lo stesso Id e sono dello stesso tipo di oggetto dovrebbero essere uguali. Tuttavia quando uso GetType() per ottenere il tipo dell'oggetto, restituirà il tipo di proxy NHibernate. Quindi, questo codice:

bool IEqualityComparer.Equals(object x, object y) 
{ 
    // null checking code skipped here 
    if(x is DomainObject && y is DomainObject) 
    { 
      return ((DomainObject) x).Id == ((DomainObject) y).Id 
        && x.GetType() == y.GetType(); 
    } 
    return x.Equals(y); 
} 

non funziona correttamente, perché il tipo di x is Asset ma il tipo di y is AssetProxy21879bba3e9e47edbbdc2a546445c657.

Quindi, come si ottiene il tipo di entità su un oggetto che può essere un oggetto proxy NHibernate? vale a dire nell'esempio sopra Asset anziché AssetProxy21879bba3e9e47edbbdc2a546445c657?

+0

Sono sicuro che il 99% si tratta di un duplicato, ma sono troppo pigro in questo momento per la ricerca è: -) –

+3

Mostrami quello che duplica, ho cercato tutto lo stackoverflow per questo. –

risposta

20

È possibile ottenere il tipo reale di una delega con:

NHibernateUtil.GetClass(x); 

oppure è possibile aggiungere un metodo per DomainObject come:

public virtual Type GetTypeUnproxied() 
{ 
    return GetType(); 
} 

Che è veramente slick e non dipende direttamente NHibernate.

In alternativa, si può affrontare il problema dicendo è necessario per ottenere il vero oggetto, piuttosto che il proxy, che, se la sessione è a portata di mano, si può fare con:

session.PersistenceContext.Unproxy(x); 

Come accennato in un altro rispondi, se stai cercando di implementare equals, sarebbe una buona idea dare un'occhiata allo Sharp architecture implementation of Equals.

+1

Nota che se stai usando Castle Windsor, la GetClass potrebbe restituire il tipo Proxy.Vedi questo thread per un altro modo per risolverlo: http://stackoverflow.com/a/1420816/348841 –

2

di ottenere reali oggetto invece di delega è possibile utilizzare

session.PersistenceContext.Unproxy(proxyObject) 

ma penso che si dovrebbe guardare a Sharp architecture implementation per Equals.

+0

Va notato che probabilmente è più interessato al metodo GetTypeUnproxied() in http://github.com/codai/Sharp-Architecture/blob/master/src/SharpArch/SharpArch.Core/DomainModel/BaseObject.cs - ma +1 per un buon riferimento impl. – DanP

+0

In questo caso in realtà non ho la sessione disponibile per me in questo codice. Grazie per il riferimento a Equals nell'architettura Sharp, non si applica a me perché sto scrivendo un uguale per i test in modo che non debba gestire tutti i casi, ma era comunque un buon riferimento. E grazie Dan al link al codice GetTypeUnproxied(), questo è più quello che mi interessa. –

0

È possibile implementare una proprietà backdoor come descritto in here per ottenere l'istanza non proxy effettiva.

-1

Ho preso un diverso approccio in un progetto di produzione. Ho semplicemente un Hilow Id-generatore globale che genera ID di unico per tutti i tipi di poi posso:

// in DomainEntity 
public override bool Equals(object obj) 
{ 
    var other = obj as DomainEntity; 
    if (Id == 0) // IsTransient() 
     return ReferenceEquals(this, other); 
    else 
     return (other != null) && (Id == other.Id); 
} 

// Comparer 
bool IEqualityComparer.Equals(object x, object y) 
{ 
    return object.Equals(x, y); 
} 
Problemi correlati