2012-03-08 2 views
6

В настоящее время у меня есть следующий код:Можно ли реорганизовать этот запрос nHibernate Linq?

switch (publicationType) 
{ 
    case PublicationType.Book: 
     return Session.Query<Publication>() 
      .Where(p => p.PublicationType == PublicationType.Book) 
      .OrderByDescending(p => p.DateApproved)       
      .Take(10) 
      .Select(p => new PublicationViewModel 
      { 
       ... 
      }); 
    case PublicationType.Magazine: 
     return Session.Query<Publication>() 
      .Where(p => p.PublicationType == PublicationType.Magazine) 
      .OrderByDescending(p => p.DateApproved)       
      .Take(10) 
      .Select(p => new PublicationViewModel 
      { 
       ... 
      }); 
    case PublicationType.Newspaper 
    .... 
} 

Как вы можете видеть, что запрос является то же самое каждый раз, когда для условия publicationType исключением. Я попытался реорганизовать это, создав метод, который принимает Func, например.

private IEnumerable<PublicationViewModel> GetPublicationItems(Func<PublicationType, bool>> pubQuery) 
{ 
    return Session.Query<Publication>() 
     .Where(pubQuery)     
     .OrderByDescending(p => p.DateApproved)       
     .Take(10) 
     .Select(p => new PublicationViewModel 
     { 
      ... 
     });     
} 

private bool IsBook(PublicationType publicationType) 
{ 
    return publicationType == PublicationType.Book; 
} 

и затем вызвать этот метод, как

GetPublicationItems(IsBook); 

Но когда я делаю это я получаю ошибку: InvalidCastException: Не удается привести объект типа «NHibernate.Hql.Ast.HqlParameter» к типу 'NHibernate.Hql.Ast.HqlBooleanExpression.

Есть ли другой способ сделать это?

ответ

5

Это звучит, как вы на самом деле не нужна функция - вам просто нужно PublicationType:

private IEnumerable<PublicationViewModel> 
    GetPublicationItems(PublicationType type) 
{ 
    return Session.Query<Publication>() 
     .Where(p => p.PublicationType == type) 
     .OrderByDescending(p => p.DateApproved)       
     .Take(10) 
     .Select(p => new PublicationViewModel 
     { 
      ... 
     });     
} 

Если вы действительно это нужно более общим, чем вы, вероятно, просто нужно изменить свой код использовать дерево выражений вместо делегата (и изменить тип входа):

private IEnumerable<PublicationViewModel> GetPublicationItems(
    Expression<Func<Publication, bool>> pubQuery) 
{ 
    return Session.Query<Publication>() 
     .Where(pubQuery)     
     .OrderByDescending(p => p.DateApproved)       
     .Take(10) 
     .Select(p => new PublicationViewModel 
     { 
      ... 
     });     
} 

Вы не сможете назвать его GetPublicationItems(IsBook) в тот момент, хотя. Вы можете сделать:

GetPublicationItems(p => p.PublicationType == PublicationType.Book) 

Или:

private static readonly Expression<Func<Publication, bool>> IsBook = 
    p => p.PublicationType == PublicationType.Book; 


... 

GetPublicationItems(IsBook) 
+0

Удивительный спасибо. Я сделал свой пример слишком простым, и, как вы указали, я могу просто передать тип публикации прямо в запрос. Но обобщение, которое вы отправили после этого, было именно тем, чем я был. – Zac

0

Есть причина, вы не можете просто использовать publicationType в запросе?

return Session.Query<Publication>() 
     .Where(p => p.PublicationType == publicationType) 
     .OrderByDescending(p => p.DateApproved)       
     .Take(10) 
     .Select(p => new PublicationViewModel 
     { 
      ... 
     }); 
0

Ваша ошибка была сбита с толку делегатов с деревьями выражений.

Func - это делегат, который нельзя преобразовать в SQL. Вы могли бы просто написали это так:

Session.Query<Publication>() 
.Where(p => p.PublicationType == yourPubilcationType) 
... 

Или, если вы хотите, чтобы пройти фильтр, этот метод, как вы намекнули в вашем образце:

IEnumerable<PublicationViewModel> GetPublicationItems(Expression<Func<PublicationType, bool>> pubQuery) 
{ 
    return Session.Query<Publication>() 
     .Where(pubQuery)     
     .OrderByDescending(p => p.DateApproved)       
     .Take(10) 
     .Select(p => new PublicationViewModel 
     { 
      ... 
     });     
} 
Смежные вопросы