たとえば、表示される行数に必要なデータのみを使用して、ASP.NET Web ページの gridview コントロールにデータを入力したいと考えています。NHibernate はこれをどのようにサポートできますか?
8 に答える
ICriteria
には、SetFirstResult(int i)
取得する最初のアイテム (基本的にはページの最初のデータ行) のインデックスを示すメソッドがあります。
またSetMaxResults(int i)
、取得する行数 (つまり、ページ サイズ) を示すメソッドもあります。
たとえば、次の基準オブジェクトは、データ グリッドの最初の 10 件の結果を取得します。
criteria.SetFirstResult(0).SetMaxResults(10);
NHibernate の Futures 機能を利用してクエリを実行し、1 つのクエリで合計レコード数と実際の結果を取得することもできます。
例
// Get the total row count in the database.
var rowCount = this.Session.CreateCriteria(typeof(EventLogEntry))
.Add(Expression.Between("Timestamp", startDate, endDate))
.SetProjection(Projections.RowCount()).FutureValue<Int32>();
// Get the actual log entries, respecting the paging.
var results = this.Session.CreateCriteria(typeof(EventLogEntry))
.Add(Expression.Between("Timestamp", startDate, endDate))
.SetFirstResult(pageIndex * pageSize)
.SetMaxResults(pageSize)
.Future<EventLogEntry>();
合計レコード数を取得するには、次の手順を実行します。
int iRowCount = rowCount.Value;
先物があなたに与えるものについての良い議論はここにあります.
NHibernate 3 以降では、以下を使用できますQueryOver<T>
。
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
次のように結果を明示的に順序付けすることもできます。
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
Ayende によるこのブログ投稿で説明されているように、Linq を NHibernate に使用するのはどうですか?
コードサンプル:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
また、ページングの実装を含む、NHibernate を使用したデータ アクセスに関する NHibernate チームのブログによる詳細な投稿を次に示します。
ほとんどの場合、GridView では、データのスライスと、クエリに一致したデータの合計量の合計行数 (rowcount) を表示する必要があります。
Select count(*) クエリと .SetFirstResult(n).SetMaxResult(m) クエリの両方を 1 回の呼び出しでデータベースに送信するには、MultiQuery を使用する必要があります。
結果は、データ スライス用とカウント用の 2 つのリストを保持するリストになることに注意してください。
例:
IMultiQuery multiQuery = s.CreateMultiQuery()
.Add(s.CreateQuery("from Item i where i.Id > ?")
.SetInt32(0, 50).SetFirstResult(10))
.Add(s.CreateQuery("select count(*) from Item i where i.Id > ?")
.SetInt32(0, 50));
IList results = multiQuery.List();
IList items = (IList)results[0];
long count = (long)((IList)results[1])[0];
ページ付けに対処するための特定の構造を作成することをお勧めします。次のようなものです(私はJavaプログラマーですが、マッピングは簡単です):
public class Page {
private List results;
private int pageSize;
private int page;
public Page(Query query, int page, int pageSize) {
this.page = page;
this.pageSize = pageSize;
results = query.setFirstResult(page * pageSize)
.setMaxResults(pageSize+1)
.list();
}
public List getNextPage()
public List getPreviousPage()
public int getPageCount()
public int getCurrentPage()
public void setPageSize()
}
私は実装を提供しませんでしたが、@Jonによって提案された方法を使用できます。ここにあなたが見てみるための良い議論があります。
2 つの基準を定義する必要はありません。1 つを定義して複製することができます。nHibernate 基準を複製するには、単純なコードを使用できます。
var criteria = ... (your criteria initializations)...;
var countCrit = (ICriteria)criteria.Clone();