Mam taką strukturę danych:

public class User
{
    public Guid Id {get;set;}
    public string Name {get;set;}
    public IList<Books> Books {get;set}
}

Walczyłem z umożliwieniem sortowania użytkowników według liczby zakładek (relacja jeden-do-wielu).

Próbowałem różnych podejść zarówno z linq, kryteriami, jak i kwerendami, ale bez powodzenia, dlatego mam nadzieję, że jeden z was może pomóc.

Używam stronicowania, ponieważ mam sporo użytkowników, więc rozwiązanie musi wykonać zapytanie na SQL, a nie w pamięci na serwerze WWW.

0
Dofs 27 lipiec 2011, 16:28

2 odpowiedzi

Najlepsza odpowiedź
var loadedUser = session.Query<User>()
    .Select(u => new { u, u.Books.Count })
    .ToList()
    .OrderBy(anonym => anonym.Count)
    .Select(anonym => anonym.u);

Lub za pomocą HQL

select user
from User as user 
    left join user.Books as books
group by user
order by count(books)
1
Firo 29 lipiec 2011, 11:53
1
Jestem prawie pewien, że byłoby to bardzo powolne, ponieważ sortowanie odbywałoby się w pamięci zamiast w bazie danych SQL.
 – 
Dofs
27 lipiec 2011, 21:46
1
@Dofs: jeśli nie stronicujesz, dlaczego myślisz, że DB posortuje to szybciej? DB zrobi to również w pamięci; nie ma magicznego „wiadra do sortowania”, które istnieje poza znanym wszechświatem...
 – 
Diego Mijelshon
28 lipiec 2011, 03:57
Cześć Diego, używam stronicowania, ale nie dodałem tego do pierwotnego pytania. Jest teraz zaktualizowany. Próbowałem też twojego rozszerzenia tutaj: sessionfactory.blogspot .com/2011/02/…, ale pojawia się błąd: NoViableAltException(84@[]) i MismatchedTreeNodeException(70!=3) (przy użyciu NH 3.04)
 – 
Dofs
28 lipiec 2011, 10:36
Nie chodzi o to, że DB ma bardziej wydajne wiadro sortujące (chociaż może to zrobić, jeśli relacja jest indeksowana), chodzi o to, że zrobienie tego w pamięci programów oznacza, że ​​każdy wpis musi zostać przeniesiony przez przewód i odwzorowany na obiekt, zanim będzie mógł być uporządkowane. Ten czas sieci i mapowania może być bardzo istotny.
 – 
heneryville
2 lipiec 2013, 21:10
...oraz? Jest sortowany przed wysłaniem lub po wysłaniu. Po prostu zmieniasz miejsce, w którym to się dzieje.
 – 
Diego Mijelshon
2 lipiec 2013, 21:13

Zobacz : Uporządkuj według liczby kolekcji za pomocą ICriteria i NHibernate

select u
from User u
join u.Books b
group by u
order by count(b) asc

Lub za pomocą LINQ:

users.OrderBy(x => x.Books.Count);
0
Community 23 maj 2017, 12:58
Nie wiem, czy robię coś źle, ale NHProfiler daje mi problem n+1.
 – 
Dofs
27 lipiec 2011, 22:36
Tak, ponieważ wszystkie książki będą pobierane raz dla każdego użytkownika. Powinieneś je pobrać, gdy zapytasz o użytkowników.
 – 
mathieu
27 lipiec 2011, 23:54