1

こんなことしたい…

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

Func<ICriteria,ICriteria>しかし、これをISessionまたはに渡す方法がわかりませんICriteria

FetchMode私は標準のページング拡張メソッドを持っていますが、この拡張メソッドにはオーバーロードがあり、追加のICriteriaメソッドを渡すことができるため、または他の何かを追加で設定できます。

拡張方法:

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

編集:

過負荷がないと、次のようになります。

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();はにおいがしますが、これを変更する方法がわかりません。

どのアプローチを提案しますか?

4

2 に答える 2

0

少し遅れましたが、おい!

最も簡単な方法は、次のように、ICriteria の代わりに IQueryOver を拡張することです。

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

これにより、すべての熱心なフェッチを行うことができます (それらは行数クエリで削除されますが、基準は同じままです)。例:

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

次のように、2 つの SQL クエリが生成されます。

すべてのアイテムについて:

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;
于 2012-01-03T10:26:17.630 に答える
0

私の理解では、基準を作成するメソッドの外部から基準の動作を変更しようとしています。

したがって、次のようになります。

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

モディファイヤにチャンスを与えるために必要なことは、body を次のように変更することだけです。

return modifer(Session.CreateCriteria<T>) //the modifer gets first dibs on the criteria
           .SetFirstResult(pageSize * (page-1))
           .SetMaxResults(pageSize)
           .ToList<T>();

SetFirstResult または SetMaxResults を使用した基準で多対多および多対 1 の関係のフェッチ モードを変更すると、間違った数の行が取得される可能性があることに注意してください。

于 2010-08-31T11:16:19.493 に答える