2009-03-26 2 views
12

Qualcuno sa di un modo per lotti query NHibernate utilizzando NHibernate.Linq come si può fare con multicriteria e ICriteria oggetti?NHibernate.Linq e multicriterio

Con Multicriteri posso creare qualcosa di simile:

var crit = session.CreateMultiCriteria() 
        .Add(session.CreateCriteria(typeof(Entity1)).Add(Restrictions.Eq("Property1","Value")) 
        .Add(session.CreateCriteria(typeof(Entity2)).Add(Restrictions.Eq("Property2","Value2"));    

var result = crit.List(); 
var list1 = (IList)result[0]; 
var list2 = (IList)result[1]; 

sarebbe bello se si sostituisce la createCriteria chiamate con chiamate Linq e ottenere qualcosa di simile:

var crit = session.CreateMultiCriteria() 
       .Add(session.Linq<Entity1>().Where(x => x.Property1 == "Value1") 
       .Add(session.Linq<Entity2>().Where(x => x.Property2 == "Value2"); 

var result = crit.List(); 
var list1 = (IList<Entity1>)result[0]; 
var list2 = (IList<Entity2>)result[1]; 

stiamo usando l'API di Linq per la maggior parte delle altre query e sarebbe bello utilizzare la stessa sintassi di Linq quando è necessario eseguire anche le query di MultiCriteria.

Grazie.

risposta

4
var query = from q in session.Linq<Person>() 
      where q.FirstName.StartsWith(firstName) 
      && q.LastName.StartsWith(lastName) 
      && q.Phones.Any(p => p.Number.Contains(phone)) 
      select q; 

// This block of code was found in the NHibernate.Linq source 
// using NHibernate.Linq.Visitors; 
// using NHibernate.Engine; 
System.Linq.Expressions.Expression expression = query.Expression; 
expression = Evaluator.PartialEval(expression); 
expression = new BinaryBooleanReducer().Visit(expression); 
expression = new AssociationVisitor((ISessionFactoryImplementor)session.SessionFactory).Visit(expression); 
expression = new InheritanceVisitor().Visit(expression); 
expression = CollectionAliasVisitor.AssignCollectionAccessAliases(expression); 
expression = new PropertyToMethodVisitor().Visit(expression); 
expression = new BinaryExpressionOrderer().Visit(expression); 
NHibernateQueryTranslator translator = new NHibernateQueryTranslator(session); 
object results = translator.Translate(expression, ((INHibernateQueryable)query).QueryOptions); 

// My LINQ query converted to ICriteria 
ICriteria resultsCriteria = results as ICriteria; 
// Convert to criteria that returns the row count 
ICriteria rowCountCriteria = CriteriaTransformer.TransformToRowCount(resultsCriteria); 

IList multiResults = session.CreateMultiCriteria() 
    .Add(resultsCriteria.SetMaxResults(20)) 
    .Add(rowCountCriteria) 
    .List(); 

IList people = (IList)multiResults[0]; 
int resultsCount = (int)((IList)multiResults[1])[0]; 

da http://rndnext.blogspot.com/2009/05/using-nhibernate-multicriteria-and-linq.html

3

NHibernate.Linq stesso utilizza NHibernateQueryTranslator per tradurre dall'espressione LINQ a un ICriteria. Puoi farlo anche tu, quindi passare l'ICriteria risultante nella tua IMultiCriteria.

+0

Grazie, dovrò esaminare la NHibernateQueryTranslator e vedere se riesco a far funzionare qualcosa. –

0

Ho una soluzione che permette sia di dosaggio a strategie di caricamento diretto usando NHibernate LINQ, ma il codice è il re del complesso. È troppo da elencare qui. Ne parlerò sul mio blog su devlicio.us molto presto. Aggiornerò questo commento quando scriverò il primo post.

+0

Non vedo l'ora di leggere il tuo post. –