NHibernate - dynamic QueryOver parameter

一个人想着一个人 提交于 2020-01-24 20:49:06

问题


I have an MVC project that I'm trying to setup a nice paging solution for.

I have several tables in SQL Server that have several thousand rows that I would like to be able to page through. 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.

The exception I'm seeing using "Contains" is:

Unrecognised method call: 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!


回答1:


QueryOver is not LINQ, and it only accepts a very limited set of expressions.

My suggestion is that you rewrite your method to use LINQ, by replacing QueryOver with Query. 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:

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



回答2:


With the QueryOver you have to use the extension method IsLike, so x.Name.IsLike(q, MatchMode.Anywhere).



来源:https://stackoverflow.com/questions/5044851/nhibernate-dynamic-queryover-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!