Il mio progetto attuale utilizza NHibernate 3.0b1 e l'API NHibernate.Linq.Query<T>()
. Sono abbastanza fluente in LINQ, ma non ho assolutamente alcuna esperienza con HQL o l'API ICriteria. Una delle mie query non è supportata dall'API IQueryable, quindi presumo di dover utilizzare una delle API precedenti, ma non ho idea da dove iniziare.Come si esprime questa query LINQ utilizzando l'API ICiteria NHibernate?
Ho provato a cercare sul Web una buona guida "iniziale" per ICriteria, ma gli unici esempi che ho trovato sono troppo semplicistici da applicare qui o troppo avanzati per me da capire. Se qualcuno ha dei buoni materiali didattici da passare, sarebbe molto apprezzato.
In ogni caso, il modello a oggetti che sto interrogando contro si presenta così (notevolmente semplificate, le proprietà non rilevanti omesso):
class Ticket {
IEnumerable<TicketAction> Actions { get; set; }
}
abstract class TicketAction {
Person TakenBy { get; set; }
DateTime Timestamp { get; set; }
}
class CreateAction : TicketAction {}
class Person {
string Name { get; set; }
}
Un Ticket
ha una collezione di TicketAction
descrivere la sua storia. I sottotipi TicketAction
includono CreateAction
, ReassignAction
, CloseAction
, ecc. Tutti i biglietti hanno un CreateAction
aggiunto a questa raccolta una volta creati.
Questa query LINQ cerca i ticket creati da qualcuno con il nome specificato.
var createdByName = "john".ToUpper();
var tickets = _session.Query<Ticket>()
.Where(t => t.Actions
.OfType<CreateAction>()
.Any(a => a.TakenBy.Name.ToUpper().Contains(createdByName));
Il metodo OfType<T>()
provoca un NotSupportedException
per essere gettato. Posso farlo usando ICriteria?
preferirei non dover aggiungere un back-riferimento ad un 'TicketAzione 'di TicketAction' se posso aiutarlo dato che questo introdurrà altri problemi, ma grazie per il suggerimento. :) –
L'altro modo in cui abbiamo gestito situazioni come questa era di creare effettivamente l'HQL in un generatore di stringhe. Abbiamo provato a utilizzare le espressioni da Linq a Nhibernate, ma anche quelle non supportano le raccolte quando la raccolta si trova sul lato dell'oggetto. Sfortunatamente, il metodo "Contiene" non traduce in Linq su nHibernate. – Josh
Ho seguito il tuo suggerimento dopo tutto (aggiungendo un riferimento al Ticket su TicketAction), ma alla fine ho riscontrato un errore: "NHibernate.QueryException: impossibile risolvere la proprietà: TakenBy.Nome di: CreateAction " –