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

Zac*_*Zac 6 c# linq nhibernate

目前我有以下代码:

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
    .... 
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,除了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;
}
Run Code Online (Sandbox Code Playgroud)

然后调用此方法

GetPublicationItems(IsBook);
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,我得到错误:InvalidCastException:无法将类型为'NHibernate.Hql.Ast.HqlParameter'的对象强制转换为'NHibernate.Hql.Ast.HqlBooleanExpression'.

还有另一种方法吗?

Jon*_*eet 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
        {
            ...
        });                
}
Run Code Online (Sandbox Code Playgroud)

如果你真的需要它更通用,你可能只需要更改代码以使用表达式树而不是委托(并更改输入类型):

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
        {
            ...
        });                
}
Run Code Online (Sandbox Code Playgroud)

但是,您无法GetPublicationItems(IsBook)在此时调用它.你可以这样做:

GetPublicationItems(p => p.PublicationType == PublicationType.Book)
Run Code Online (Sandbox Code Playgroud)

要么:

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


...

GetPublicationItems(IsBook)
Run Code Online (Sandbox Code Playgroud)