本文介绍了NHibernate-使用ICriteria和可选的ICriteria调用进行分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我想做这样的事情...

I want to do something like this...

return GetSession()
        .ToPagedList<Employee>(page, pageSize,
        x=> x.SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager));

但是我不知道如何将此Func<ICriteria,ICriteria>传递到ISessionICriteria.

But I don't know how to pass this Func<ICriteria,ICriteria> into the ISession or ICriteria.

我有一个标准的分页扩展方法,并且此扩展方法应该有一个重载,在这里我可以传递其他ICriteria方法,以便可以附加地设置FetchMode或其他内容.

I have a standard paging extension method and this extension method shall have an overload where I can pass additional ICriteria methods, so that I can additionally set up the FetchMode or something else.

扩展方法:

public static class CriteriaExtensions
{
    public static PagedList<T> ToPagedList<T>(this ISession session, int page, int pageSize) where T : Entity
    {

        var totalCount = TotalCount<T>(session);

        return new PagedList<T>(session.CreateCriteria<T>()
            .SetFirstResult(pageSize * (page - 1))
            .SetMaxResults(pageSize * page)
            .Future<T>().ToList(), page, pageSize, totalCount);

    }

    public static PagedList<T> ToPagedList<T>(this ISession session, int page, int pageSize, Func<ICriteria, ICriteria> action) where T : Entity
    {
        var totalCount = TotalCount<T>(session);

        ...
    }

    private static int TotalCount<T>(ISession session) where T : Entity
    {
        return session.CreateCriteria<T>()
            .SetProjection(Projections.RowCount())
            .FutureValue<Int32>().Value;
    }
}

没有过载,它将看起来像这样:

Without an overload it would look like this:

return GetSession()
                .CreateCriteria<Employee>()
                .SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager)
                .ToPagedList<Employee>(page, pageSize);

扩展方法:

public static class CriteriaExtensions
{
    public static PagedList<T> ToPagedList<T>(this ICriteria criteria, int page, int pageSize) where T : Entity
    {
        var copiedCriteria = (ICriteria) criteria.Clone();

        var totalCount = TotalCount(criteria);

        return new PagedList<T>(copiedCriteria
            .SetFirstResult(pageSize * (page - 1))
            .SetMaxResults(pageSize * page)
            .Future<T>().ToList(), page, pageSize, totalCount);
    }

    private static int TotalCount(ICriteria criteria)
    {
        return criteria
            .SetProjection(Projections.RowCount())
            .FutureValue<Int32>().Value;
    }
}

线路var copiedCriteria = (ICriteria) criteria.Clone();在这里闻起来,但我不知道如何更改.

The line var copiedCriteria = (ICriteria) criteria.Clone(); smells here, but I don't know how to change this.

您会建议哪种方法?

推荐答案

有点晚了,但是,嘿!

最简单的方法是扩展IQueryOver而不是ICriteria,如下所示:

The easiest thing to do is to extend IQueryOver instead of ICriteria, like so:

public static PaginatedList<T> Paginate<T>(this IQueryOver<T, T> instance, int page, int pageSize) where T : Entity {
    var countCriteria = instance.ToRowCountQuery();
    var totalCount = countCriteria.FutureValue<int>();

    var items = instance.Take(pageSize).Skip((page- 1)*pageSize).List<T>();
    return new PaginatedList<T>(items, page, pageSize, totalCount.Value);
}

这将允许您进行所有急切的提取操作(它们将在行计数查询中删除,但条件将保持不变).示例:

This will allow you to do all your eager fetching (they will be removed in the row count query, but the criterias will remain the same). Example:

session.QueryOver<Customer>()
       .Where(x => x.Status == CustomerStatus.Preferred)
       .Fetch(x => x.Orders).Eager
       .Paginate(1, 10);

将产生两个sql查询,如下所示:

Will yield two sql queries, like this:

对于所有项目:

SELECT this_.id, this_.url, order_.sum FROM Customers this_ LEFT OUTER JOIN orders order_ ON this_.id = order_.customer_id WHERE this_.status = 1 LIMIT 10;

计数:

SELECT count(*) as y0_ FROM Customers this_ WHERE this_.type = 1;

这篇关于NHibernate-使用ICriteria和可选的ICriteria调用进行分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 08:45