简体   繁体   English

NHibernate-动态QueryOver参数

[英]NHibernate - dynamic QueryOver parameter

I have an MVC project that I'm trying to setup a nice paging solution for. 我有一个MVC项目,我正在尝试为其建立一个不错的分页解决方案。

I have several tables in SQL Server that have several thousand rows that I would like to be able to page through. 我在SQL Server中有几张表,这些表有几千行,我希望能够对其进行分页。 If I don't have any type of filter to apply to the paging, it works great. 如果我没有任何类型的过滤器可应用于分页,则效果很好。 This is the method I'm using to do that: 这是我用来执行此操作的方法:

    public virtual PagedList<T> GetPagedData(int startIndex, int count) {
        var rowCount = session.CreateCriteria(typeof(T)).SetProjection(Projections.RowCount()).FutureValue<Int32>().Value;
        var pageOfItems = session.CreateCriteria(typeof(T)).SetFirstResult(startIndex).SetMaxResults(count).List<T>();
        return new PagedList<T>(pageOfItems, startIndex, count, rowCount);
    }

I also want the ability to pass in a query to narrow the results down even further, and return a new paging table. 我还希望能够传递查询以进一步缩小结果范围并返回新的分页表。 What I have so far is: 到目前为止,我有:

    public virtual PagedList<T> GetPagedData<T>(int startIndex, int count, System.Linq.Expressions.Expression<Func<T, bool>> predicate) where T : class {
        var rowCount = session.QueryOver<T>().Where(predicate).Select(Projections.RowCount()).FutureValue<Int32>().Value;

        var pageOfItems = session.QueryOver<T>().Where(predicate).Skip(startIndex).Take(count).List<T>();
        return new PagedList<T>(pageOfItems, startIndex, count, rowCount);
    }

The call to this would look something like this: 对此的调用看起来像这样:

networks = mRepository.GetPagedData<Network>(page ?? 1, pageSize, x => x.Name.Contains(q));

The problem is, it doesn't like the "Contains" expression. 问题是,它不喜欢“包含”表达式。 If I do an exact match, it works fine (x.Name == q), but I don't get the results I'm after. 如果我进行完全匹配,则可以正常工作(x.Name == q),但我没有得到我想要的结果。

The exception I'm seeing using "Contains" is: 我使用“包含”看到的异常是:

Unrecognised method call: System.String:Boolean Contains(System.String) 无法识别的方法调用:System.String:Boolean Contains(System.String)

Does anyone have an idea how to get this to accept an expression like this dynamically? 有谁知道如何让它动态接受这样的表达式? I have a base repository class that I've put this in, because I'll use the same type of behavior for several other tables. 我有一个基本的存储库类,因为我将对其他几个表使用相同类型的行为。 I could write a separate method for each table, but I would rather do this dynamically if it's possible. 我可以为每个表编写一个单独的方法,但是如果可能的话,我宁愿动态地执行此操作。

Thanks for any advice! 感谢您的任何建议!

QueryOver is not LINQ, and it only accepts a very limited set of expressions. QueryOver不是LINQ,它仅接受非常有限的一组表达式。

My suggestion is that you rewrite your method to use LINQ, by replacing QueryOver with Query . 我的建议是,通过将QueryOver替换为Query来重写使用LINQ的方法。 The only problem is that it's harder to do the Count using a future query (see this answer for details) 唯一的问题是,使用将来的查询很难进行计数(有关详细信息,请参见此答案

Here's a version without Future: 这是没有Future的版本:

public virtual PagedList<T> GetPagedData<T>(int startIndex, int count,
               Expression<Func<T, bool>> predicate) where T : class
{
    var query = session.Query<T>().Where(predicate);
    var rowCount = query.Count();
    var page = query.Skip(startIndex).Take(count).List<T>();
    return new PagedList<T>(pageOfItems, startIndex, count, rowCount);
}

使用QueryOver ,必须使用扩展方法IsLike ,所以必须使用x.Name.IsLike(q, MatchMode.Anywhere)

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

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