NHibernate.Linq и MultiCriteria - PullRequest
       20

NHibernate.Linq и MultiCriteria

12 голосов
/ 26 марта 2009

Кто-нибудь знает способ пакетирования запросов NHibernate с помощью NHibernate.Linq, как вы можете делать с объектами MultiCriteria и ICriteria?

С помощью MultiCriteria я могу создать что-то вроде этого:

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

Было бы неплохо, если бы я заменил вызовы CreateCriteria на вызовы Linq и получил что-то вроде этого:

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

Мы используем API Linq для большинства других наших запросов, и было бы неплохо использовать тот же синтаксис Linq, когда нам нужно также выполнять запросы MultiCriteria.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 29 мая 2009
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];

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

3 голосов
/ 09 апреля 2009

NHibernate.Linq использует NHibernateQueryTranslator для перевода из выражения LINQ в ICriteria. Вы можете сделать это тоже, а затем передать полученный ICriteria в ваш IMultiCriteria.

0 голосов
/ 21 апреля 2009

У меня есть решение, которое позволяет обеим пакетировать стратегии выборки с помощью NHibernate Linq, но код - король сложного. Это слишком много, чтобы перечислять здесь. Я собираюсь поговорить об этом в своем блоге на devlicio.us довольно скоро. Я обновлю этот комментарий, когда напишу первый пост.

...