Можно ли реорганизовать этот запрос nHibernate Linq? - PullRequest
6 голосов
/ 08 марта 2012

В настоящее время у меня есть следующий код:

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
    .... 
}

Как видите, запрос каждый раз один и тот же, за исключением условия публикации типа. Я попытался реорганизовать это путем создания метода, который принимает 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'.

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

Ответы [ 3 ]

5 голосов
/ 08 марта 2012

Звучит так, будто вам на самом деле не нужна функция - вам просто нужно 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 голосов
/ 08 марта 2012

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

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
        {
            ...
        });                
}
0 голосов
/ 08 марта 2012

Есть ли причина, по которой вы не можете просто использовать тип публикации в запросе?

return Session.Query<Publication>()
       .Where(p => p.PublicationType == publicationType)
       .OrderByDescending(p => p.DateApproved)                        
       .Take(10)
       .Select(p => new PublicationViewModel
       {
           ...
       });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...