Kolejne pytanie o nhib.
Klasy i mapowanie jak w pytaniu, w którym już mi pomogliście:
public class Task
{
public virtual int Id {get;set;}
public virtual Person Author { get; set; }
public virtual string Title { get; set; }
public virtual IList<Domain.TaskAssignement> Assignements { get; set; }
}
public class Person
{
public virtual int Id {get;set;}
public virtual string Name {get;set;}
...
}
public class TaskAssignement
{
public virtual int Id {get;set;}
public virtual Person Person { get;set; }
public virtual Task Task { get;set; }
public virtual DateTime JoinDate {get;set;}
public virtual bool IsDeleted {get;set;}
}
Czyli jedno zadanie ma kilka osób przypisanych do jego wykonania, jedna osoba ma wiele zadań. Sytuacja dość standardowa.
Teraz pytanie. Potrzebuję w zależności od kryteriów wyszukiwania wprowadzanych przez użytkownika wybierać z bazy te zadania, które je spełniają. Doszedłem do miejsca, w którym jestem trochę zagubiony.
Assignements w pojedynczym Task posiadają dowiązanie do osoby. Użytkownik aplikacji chce wyszukać wszystkie zadania przypisane do użytkownika o ID = X. Jednocześnie załadowanie pełnych list Assignements w każdym z zadań nie jest niezbędne - grid w którym pokazywane są zadania nie korzysta z nich.
W pierwszym podejściu ściągałem listę zadań i używając LINQ filtrowałem ją po stronie C#, to jednak wywoływało lazy-loading i N+1 zapytań dla każdego wiersza zadania. Nie chcę wyłączać lazy-loadingu dla "Bag" Assignements - przyda się w innym miejscu.
Jak skonstruować zapytanie w NHibernate, aby:
- zminimalizować liczbę niepotrzebnych zapytań (200 zadań * 3 przypisania - robi się sporo)
- przefiltrować zapytania po stronie DB w zależności od assignements jednak nie ściągać ich
- w ostateczności - ściągnąć zadania (wraz z ich assignements) jednak tylko te, które spełniają zadane kryteria
Mam do wykorzystania: NHibernate 2, C# 3.5, Fluent, NHibernate.Linq
Tutaj znalazłem pośrednie rozwiązanie:
string sql = "from Order o" +
" inner join fetch o.OrderLines" +
" inner join fetch o.Customer" +
" where o.Id=:id";
fromDb = session.CreateQuery(sql)
.SetGuid("id", _order.Id)
.UniqueResult<Order>();
Czy da się je wygenerować dla listy używając NHibernate.Linq ?
Jak Wy radzicie sobie z podobnymi zapytaniami / problemami? Generalnie chciałbym załadować listę zadań w następującym algorytmie:
- Użytkownik wprowadza warunki wyszukiwania
- Tworzę ISession, z ITaskRepository wyciągam tylko zadania spełniające warunki
- Zamykam ISession przypisując wynik do listy lokalnej
- Listą wypełniam grida, z pewnością, że nie zaskoczy mnie LazyloadingException związany z zamkniętą sesją
Czy taki scenariusz jest dobry? Jak Wy realizujecie takie zadania?