Domanda

Sto utilizzando una query denominata personalizzata con NHibernate che desidero restituire una raccolta di oggetti Person. L'oggetto Person non è mappato con un mapping NHibernate, il che significa che sto ottenendo la seguente eccezione:

  

System.Collections.Generic.KeyNotFoundException:   La chiave fornita non era presente nel file   dizionario.

Viene generato quando viene creata la Session perché non riesce a trovare il nome della classe quando chiama NHibernate.Cfg.Mappings.GetClass (String className). Tutto questo è abbastanza comprensibile, ma mi chiedevo se ci fosse un modo per dire a NHibernate di usare la classe anche se non ho una mappatura per essa?

È stato utile?

Soluzione 5

Per risolvere questo problema, ho finito per usare TupleToPropertyResultTransformer e fornire l'elenco dei valori delle proprietà. Vi sono alcune limitazioni, la principale è che la query SQL deve restituire i risultati nello stesso ordine in cui si forniscono le proprietà al costruttore TupleToPropertyResultTransformer.

Vengono dedotti anche i tipi di proprietà, quindi è necessario fare attenzione con le colonne decimali che restituiscono solo valori interi, ecc. Oltre a ciò, l'uso di TupleToPropertyResultTransformer ha fornito un modo ragionevolmente semplice di utilizzare una query SQL per restituire una raccolta di oggetti senza mappare esplicitamente l'oggetto oggetti all'interno di NHibernate.

Altri suggerimenti

Perché non usi:

query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));

Inserirà i dati di ciascuna colonna della query nelle proprietà dell'oggetto Person usando l'alias di colonna come nome della proprietà.

Come si può creare una query che restituisca istanze di un tipo che non è mappato?

Penso che Michal abbia un punto qui, e forse dovresti dare un'occhiata alle proiezioni. (Almeno, questo è quello che penso tu stia cercando).

Si crea una query su un tipo mappato, quindi è possibile "proiettare" tale query su un "DTO". Per fare ciò, dovrai 'importare' la tua classe Person, in modo che sia nota a NHibernate e dovrai usare un Transformer di risultati.

Qualcosa del genere:

ICriteria crit = session.CreateCriteria (typeof(Person));

// set some filter criteria

crit.SetProjection (Projections.ProjectionList()
                     .Add (Property("Name"), "Name")
                     .Add (Property( ... )
                   );

crit.SetResultTransformer(Transformers.AliasToBean(typeof(PersonView));

return crit.List<PersonView>();

Ma ciò significa che dovrai importa la classe, in modo che NHibernate ne sia a conoscenza.

Usando la classe, NHibernate avrebbe sostanzialmente indovinato tutto ciò che riguardava, inclusa la tabella che intendevi usare per Persona e le mappature dei campi. Probabilmente NHibernate potrebbe essere hackerato per eseguire l'associazione dinamica in base alla corrispondenza dei nomi o qualcosa del genere, ma l'idea generale è quella di creare i mapping da semplici oggetti dati vecchi ai campi del database utilizzando i file xml.

Se non c'è davvero un buon motivo per non mappare la classe, semplicemente aggiungendo la mappatura otterrai i migliori risultati ...

Detto questo, non è possibile utilizzare una query con nome per iniettare direttamente i risultati in una classe non mappata. Dovresti dirgli quali colonne mettere in quali campi o, in altre parole, una mappatura. ;) Tuttavia, puoi restituire valori scalari da una query denominata e puoi prendere quelle matrici di oggetti e creare la tua raccolta manualmente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top