繁体   English   中英

是否有可能重构这个nHibernate Linq查询?

[英]Is it possible to refactor this nHibernate Linq query?

目前我有以下代码:

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'。

还有另一种方法吗?

听起来你真的不需要一个函数 - 你只需要一个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)

您是否有理由不能在查询中使用publicationType?

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

你的错误让代表们对表达树感到困惑。

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
        {
            ...
        });                
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM