NHibernate.Linq and MultiCriteria

馋奶兔 提交于 2019-12-04 10:40:27

问题


Anybody know of a way to batch NHibernate queries using NHibernate.Linq like you can do with MultiCriteria and ICriteria objects?

With MultiCriteria I can create something like this:

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];

It would be nice if I replace the CreateCriteria calls with Linq calls and get something like this:

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];

We're using the Linq API for most of our other queries and it would be nice to use the same Linq syntax when we need to run MultiCriteria queries as well.

Thanks.


回答1:


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];

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




回答2:


NHibernate.Linq itself uses NHibernateQueryTranslator to translate from the LINQ expression to an ICriteria. You could do this too, then pass the resulting ICriteria into your IMultiCriteria.




回答3:


I have a solution that enables both batching a fetching strategies using NHibernate Linq, but the code is king of complex. It's too much to list here. I am going to be talking about it on my blog on devlicio.us pretty soon. I'll update this comment when I write the first post.



来源:https://stackoverflow.com/questions/684696/nhibernate-linq-and-multicriteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!