Fluent NHibernate – ProjectionList – ICriteria restituisce valori nulli

Sono abbastanza nuovo in NHibernate, ma ho cercato su Google e non ho trovato nulla per aiutare con questo problema. Spero che voi ragazzi possa! 😉 Sto cambiando i nomi di proprietà e metodi, perché questo codice è di proprietà della società, ma in fondo questo è quello che ho bisogno di aiuto.

Ho il seguente scenario:

My Domain Entity:

public class Structure { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual Person Manager { get; set; } //I need to fill here. //and others } 

La mia class di mappa:

 public class MapStructure : ClassMap { public MapStructure() { Table("TB_Structure"); Id(x => x.Id).Column("Id").GeneratedBy.Identity(); Map(x => x.Name).Column("Name"); References(x => x.Manager).Column("PersonId").Fetch.Join().NotFound.Ignore(); //... } } 

repository:

      public IEnumerable SelectByColumns() { ICriteria searchCriteria = _sessao.CreateCriteria("this"); searchCriteria.CreateAlias("this.Manager", "Manager"); //Only for example purpose. Those columns come as an array string parameter, but the treatment is the same one. var columns = Projections.ProjectionList(); columns.Add(Projections.Property("Manager.Id")); columns.Add(Projections.Property("Manager.Name")); columns.Add(Projections.Property("Manager.Document")); searchCriteria.SetProjection(columns); searchCriteria.SetResultTransformsr(Transformsrs.AliasToBean()); return searchCriteria.List(); } 

    E infine la chiamata:

     public IEnumerable GetManager() { using (IDbSession dbSession = _sessionFactory.Create()) { try { IRepository _repository = dbSession.CreateRepository(); IEnumerable structureList = _repository.SelectByColumns(); var managerList = (from structure in structureList where structure.Manager != null select new Person() { Id = structure.Manager.Id, Name = structure.Manager.Name, Document = structure.Manager.Document }); return managerList.OrderBy(x => x.Name); } catch (Exception) { throw; } } } 

    Questo mi genera una query sql come di seguito:

     SELECT manager1_.PersonId as y0_, manager1_.Name as y1_, manager1_.Document as y2_ FROM TB_Structure this_ inner join TB_Person manager1_ on this_.ManagerId=manager1_.PersonId 

    E questo è esattamente ciò di cui ho bisogno. Se eseguo questa query in Management Studio, ho ottenuto tutti i risultati che mi aspettavo.

    Risultato

    Ma quando raggiungo la var managerList, la strutturaLista ha tutti i record restituiti da sql, ma tutti con valori null come mostrato:

    Dopo aver eseguito query sql

    Ho già provato con CreateAlias, CreateCriteria, restituisco IList , restituisco IEnumerable. Ho già trasformato Transformers.AliasToBean () in Transformers.AliasToEntityMap. Un sacco di cose diverse ho trovato su google, ma ho sempre ottenuto lo stesso risultato.

    Apprezzo qualsiasi aiuto, e grazie per il tuo tempo!

    Ci sei quasi. Ciò di cui abbiamo bisogno è di convertire correttamente le Proiezioni in albero quadro / object. Ciò richiederebbe due passaggi:

    I. uso l’alias per ogni colonna

    Column Alias, è utile più per l’elaborazione ex post che per la generazione di istruzioni SQL. Ma è un must per il prossimo passo. Quindi, invece di questo:

     columns.Add(Projections.Property("Manager.Id")); columns.Add(Projections.Property("Manager.Name")); columns.Add(Projections.Property("Manager.Document")); 

    abbiamo bisogno di questo:

     columns.Add(Projections.Property("Manager.Id").As("Manager.Id"); columns.Add(Projections.Property("Manager.Name").As("Manager.Name")); columns.Add(Projections.Property("Manager.Document").As("Manager.Document")); 

    In realtà, questo sarebbe sufficiente se usassimo l’ quadro di primo livello (no JOIN) . Per l’albero di riferimento JOINed (many-to-one) non funzionerà. ma

    II. usa un trasformatore di risultati personalizzato

    Come sempre, NHibernate offre molti punti di apertura per le estensioni personalizzate. Uno di questi sarebbe IResultTransformsr personalizzato. Quello di cui abbiamo bisogno è l’albero di riferimento di cui abbiamo bisogno è qui:

    • DeepTransformsr

    Avendo ciò nella nostra soluzione dovremmo invece questo:

     searchCriteria.SetResultTransformsr(Transformsrs.AliasToBean()); 

    Usa questo:

     searchCriteria.SetResultTransformsr(new DeepTransformsr()); 

    Questa implementazione dipende fortemente dall’impostazione dell’alias corretto, descrivendo le proprietà dell’ quadro reale (per utilizzare la reflection per trovare cosa impostare). Quindi il primo punto – alias colonna / proprietà è davvero essenziale