Linq nHibernate i DevExpress grid z ServerMode

Co innego poznawać technologie na prostych przykładach a co innego zmierzyć się z konkretnym problemem.
Windowsowy grid od DevExpressa ma jedną bardzo ciekawą i przydatną funkcjonalność - ServerMode. A polega to na tym że jeśli grid jako dataSource ma podpięty LinqDataSource i ustawioną propercje ServerMode, to sam sobie radzi z dynamicznym stronicowiem czyli zaciąga sobie tylko dane które aktualnie wyświetla.
Fajnie. Dodajmy do tego wyszukiwanie (oczywiście tego wbudowanego do grida aby wszytko razem działało), i jeszcze jeden drobny szczegół - normalizacje bazy danych.
Taka mała struktura w której Nazwa subiekta przechowywana jest w osobnej tabeli. Chcemy więc wyświetlić dane z tabeli parenta oraz nazwę z tabeli childa (tak naprawdę powiązannie będzie 1:1 zawsze tylko jeden child jest aktualny).
Skoro tylko jeden child jest aktualny można by więc zrobić propercję na poziomie parenta, która będzie zwracać Name z childa.
Tworzymy więc partial class dla naszego Subject i dopisujemy:
public string Name
{
    get{ return SubjectNameNIPs.DefaultIfNull(new SubjectNameNIP()).FirstOrDefault().Name;}
}
Takie rozwiązanie działa. Wprawdzie nie wypróbowałam wyszukiwania po takim atrybucie, jednak to by było i tak za proste ;)
SubjectListLinqDataContext context = new SubjectListLinqDataContext(ConnectionStrings[DATABASE_NAME]); 
context.ObjectTrackingEnabled = false;
Właściwość ObjectTrackingEnabled = false sygnalizuje DataContext żeby nie pamiętał zmian jakie zachodzą w obiektach. Z jednej strony zyskujemy dodatkowy przyrost wydajności dla list które same w sobie nie wymagają pamiętania stanu z drugiej strony... umożliwiamy odświeżenie listy po modyfikacji obiektu inną metodą niż przy użyciu linqa.
Jednak Name - przestaje działać.
Dzieje się tak ponieważ jeśli ObjectTrackingEnabled = false to również DeferredLoadingEnabled = false i wtedy aby załadować childy pozostaje LoadWith
Od razu analogiczną sytuacją wydała mi się nHibernatowa StatelessSession.
Spróbujmy więc LoadWith
SubjectListLinqDataContext context = new SubjectListLinqDataContext(ConnectionStrings[DATABASE_NAME]); 
context.ObjectTrackingEnabled = false;
var lo = new System.Data.Linq.DataLoadOptions();
lo.LoadWith<
SubjectList>(a => a.SubjectNameNIPs);
,context.LoadOptions = lo;
Sukces. Przefiltrujmy po polu Name... porażka.
Grid nie potrafił zadać zapytania, za bardzo mnie to nie dziwi szczególnie jeśli warunek wyboru aktualnego childa jest bardziej skomplikowany.
Moje pomysły się wyczerpały, dlatego logika tego połączenia została przeniesiona do bazy danych w postaci ComputedColumn dla którego formułę ustawić należy na wywołanie funkcji zwracającej Name z tabeli childów.
Najszybszym rozwiązaniem (jeśli chodzi o wykonywanie zapytania na bazie) była by redundancja danych.
Oczywiście można pisać własne selecty dla LinqToSql bądź widoki na bazie, jednak poszukiwane było rozwiązanie bardzo szybkie w realizacji a przeciągnij i ciesz sie DataContext wygłądało najbardziej obiecująco bez konieczności przeróbek.
A gdzie w tm wszystkim jest nHibernate?
Otórz w pliku mapowania nHibernate powiada opcje Formula

Jeśli jedynym twoim narzędziem jest młotek każdy problem wygląda jak gwóźdź.
Ja powiększyłam zasób różnorodnych gwoździ.

Komentarze

Popularne posty