首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate -使用ICriteria和可选的ICriteria调用进行分页

NHibernate -使用ICriteria和可选的ICriteria调用进行分页
EN

Stack Overflow用户
提问于 2010-08-25 18:58:08
回答 2查看 1.9K关注 0票数 1

我想做这样的事..。

代码语言:javascript
复制
return GetSession()
        .ToPagedList<Employee>(page, pageSize, 
        x=> x.SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager));

但我不知道如何将这个Func<ICriteria,ICriteria>传递给ISessionICriteria

我有一个标准的分页扩展方法,这个扩展方法应该有一个重载,在这里我可以传递额外的ICriteria方法,这样我就可以额外地设置FetchMode或其他什么东西了。

扩展方法:

代码语言:javascript
复制
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;
    }
}

编辑:

如果没有过载,它将是这样的:

代码语言:javascript
复制
return GetSession()
                .CreateCriteria<Employee>()
                .SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager)
                .ToPagedList<Employee>(page, pageSize);

扩展方法:

代码语言:javascript
复制
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();这一行闻起来很难闻,但我不知道该如何改变它。

你会建议采用哪种方法?

EN

回答 2

Stack Overflow用户

发布于 2010-08-31 11:16:19

根据我的理解,您正在尝试从创建它的方法之外修改条件的行为。

因此,你有:

代码语言:javascript
复制
public IList<T> GetPageOf<T>(int page, int pageSize, Func<ICriteria,ICriteria> modifier)
{
    return Session.CreateCriteria<T>()
           .SetFirstResult(pageSize * (page-1))
           .SetMaxResults(pageSize)
           .ToList<T>();
}

要给修饰符一个机会,您所需要做的就是将身体更改为:

代码语言:javascript
复制
return modifer(Session.CreateCriteria<T>) //the modifer gets first dibs on the criteria
           .SetFirstResult(pageSize * (page-1))
           .SetMaxResults(pageSize)
           .ToList<T>();

请注意,在使用SetFirstResult或SetMaxResults的条件中更改多对多和多对一关系的获取模式可能会导致检索错误的行数。

票数 0
EN

Stack Overflow用户

发布于 2012-01-03 10:26:17

有点晚了,但是嘿!

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

代码语言:javascript
复制
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);
}

这将允许您执行所有急切的抓取(它们将在行计数查询中删除,但标准将保持不变)。示例:

代码语言:javascript
复制
session.QueryOver<Customer>()
       .Where(x => x.Status == CustomerStatus.Preferred)
       .Fetch(x => x.Orders).Eager
       .Paginate(1, 10);

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

对于所有项目:

代码语言:javascript
复制
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;

至于伯爵:

代码语言:javascript
复制
SELECT count(*) as y0_ FROM Customers this_ WHERE this_.type = 1;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3569281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档