Ho un obbligo di caricare un oggetto complesso chiamato Nodo ... bene il suo non è quel complesso ... sembra che segue: -eager loading Utilizzando Fluent NHibernate/NHibernate & Automapping
Un Nodo ha un riferimento EntityType che ha una uno a molti con Proprietà che a sua volta ha una uno a molti con PorpertyListValue
public class Node
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType Etype
{
get;
set;
}
}
public class EntityType
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual IList<Property> Properties
{
get;
protected set;
}
public EntityType()
{
Properties = new List<Property>();
}
}
public class Property
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType EntityType
{
get;
set;
}
public virtual IList<PropertyListValue> ListValues
{
get;
protected set;
}
public virtual string DefaultValue
{
get;
set;
}
public Property()
{
ListValues = new List<PropertyListValue>();
}
}
public class PropertyListValue
{
public virtual int Id
{
get;
set;
}
public virtual Property Property
{
get;
set;
}
public virtual string Value
{
get;
set;
}
protected PropertyListValue()
{
}
}
Quello che un cercando di fare è caricare l'oggetto Node con tutto il bambino oggetti tutti in una volta. Nessun carico pigro. Il motivo è che ho migliaia di oggetti Node nel database e devo inviarli via cavo usando il servizio WCF. Ho incontrato il problema SQL N + 1 delle classi. Sto usando Fluent NHibernate con Automapping e NHibernate Profiler mi ha suggerito di utilizzare FetchMode.Eager per caricare gli oggetti interi in una sola volta. Sto usando il seguente qyuery
Session.CreateCriteria(typeof (Node))
.SetFetchMode("Etype", FetchMode.Join)
.SetFetchMode("Etype.Properties", FetchMode.Join)
.SetFetchMode("Etype.Properties.ListValues", FetchMode.Join)
O usando NHibernate LINQ
Session.Linq<NodeType>()
.Expand("Etype")
.Expand("Etype.Properties")
.Expand("Etype.Properties.ListValues")
Quando eseguo qualsiasi query precedente, entrambi generano una stessa query singola con tutti i esterno sinistro si unisce, che è ciò che Ho bisogno. Tuttavia, per qualche motivo, il ritorno di IList dalla query non viene caricato proprietà negli oggetti. Infatti il conteggio dei nodi restituiti è uguale al numero di righe della query, in modo che i nodi sono oggetti repeated.Moreover, le proprietà all'interno di ogni nodo vengono ripetuti, e così i Listvalues.
Quindi vorrei sapere come modificare la query precedente per restituire tutti i nodi unici con le proprietà ei valori di elenco al loro interno.
Grazie Nabeel
su google ho scoperto DistinctRootEntityResultTransformer ma che risolve solo il problema per gli oggetti radice. Sto ancora ottenendo duplicati nelle raccolte figlio. Ogni oggetto radice nella lista restituita ha qualche strano pasticcio prodotto cartesiano nel bambino collezioni con più istanze della stessa entità. Qualche idea? In attesa di Nabeel – nabeelfarid
Penso di aver trovato la soluzione, ma mi piacerebbe sapere se è la corretta. Le collezioni bambino (EType.Properties, Etype.Properties.ListValues) oggetto principale all'interno (nodo) sono IList. E ho letto nella documentazione che IList può contenere duplicati, quindi se cambio IList a IImpostare/ ICollection, quindi la query non carica istanze duplicate all'interno le collezioni bambino. Ma questa soluzione richiede un sacco di refactoring. Vorrei sapere se c'è un modo per ottenere lo stesso utilizzando IList per bambini collezioni? attesa, Nabeel – nabeelfarid
Ho lo stesso problema (utilizzando Fetchmode.Eager). Sono abbastanza deluso in NHibernate per questo. Preferirei avere un errore rispetto ai dati errati. – UpTheCreek