Twój potencjał rozwiązaniem będą obsługiwane w ramach jednej transakcji, ale będą dwie wywołania db. Jeśli musisz mieć tylko jedno wywołanie db, powinieneś użyć kwerendy wielowątkowej/przyszłej, zgodnie z sugestią peer. Aby uzyskać więcej informacji na temat przyszłej składni, sprawdź ten wpis: http://ayende.com/blog/3979/nhibernate-futures.
Oto kilka sposobów, aby osiągnąć swój scenariusz ... (połączenia 2 db)
QueryOver:
var query = session.QueryOver<Organism>();
var result = query
.Skip((Page - 1) * PageSize)
.Take(PageSize)
.List();
var rowcount = query.RowCount();
Z zestawu próbek 100 organizmach, a odpytywanie dla organizmów 11-20 , tutaj są dwa zapytania wysyłane do dB:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
SELECT count(*) as y0_ FROM Organism this_
QueryOver (1 wywołania db z przyszłości):
var query = session.QueryOver<Organism>()
.Skip((Page - 1) * PageSize)
.Take(PageSize)
.Future<Organism>();
var result = query.ToList();
var rowcount = session.QueryOver<Organism>()
.Select(Projections.Count(Projections.Id()))
.FutureValue<int>().Value;
Pytanie o tych samych danych, jak poprzednio, jest to zapytanie, które są generowane:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;SELECT count(this_.Id) as y0_ FROM Organism this_;;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
kryteria (1 połączenie dB w przyszłości)
var criteria = session.CreateCriteria<Organism>()
.SetFirstResult((Page - 1) * PageSize)
.SetMaxResults(PageSize)
.Future<Organism>();
var countCriteria = session.CreateCriteria<Organism>()
.SetProjection(Projections.Count(Projections.Id()))
.FutureValue<int>().Value;
Ponownie zapytań dla ten sam zestaw danych, kryteria z przyszłymi wynikami w tym samym zapytaniu:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;SELECT count(this_.Id) as y0_ FROM Organism this_;;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
Zauważ, że wszystkie Style zapytań skutkują dokładnie tymi samymi zapytaniami. Przyszła składnia po prostu pozwala NHibernate na wykonanie jednego wywołania bazy danych zamiast dwóch.
Jeśli używasz NHibernate 3, myślę, że najbardziej eleganckim sposobem radzenia sobie z tym jest użycie nowej składni QueryOver. (Użyłeś starej składni NHibernate.Linq w swoim proponowanym rozwiązaniu, zamiast tego lepiej nauczyć się składni QueryOver.)
Prawdopodobnie warto zauważyć, że to, czy te dwie wartości są wynikiem pojedynczego zapytania, zależy od optymalizacji zależnych od dialektu. Na przykład w SQLite są wydawane dwa zapytania, ale zachowanie jest takie samo (wszystkie transakcje futures są wykonywane jednocześnie w jak najmniejszej ilości zapytań) – AlexCuse