开发者

NHibernate - dynamic QueryOver parameter

开发者 https://www.devze.com 2023-02-12 11:02 出处:网络
I have an MVC project tha开发者_C百科t 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 throug

I have an MVC project tha开发者_C百科t 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!


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


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

0

精彩评论

暂无评论...
验证码 换一张
取 消