środa, 16 kwietnia 2014

Stronicowanie (pagination) w SQL Server - ROW_NUMBER() vs RANK() vs DENSE_RANK()

Zastanawialiście się kiedyś jak robić stronicowanie w SQL Server? Ja ostatnio musiałem coś takiego zrobić, ale nie używając żadnego ORM'a lecz jedynie gołe ADO.NET. Sprawa wydawała się być banalna, napisałem zapytanie ale okazało się, że wyniki są jakieś dziwne i jeszcze się powielają mimo tego iż miałem DISTINCTA na zapytaniu. Poszperałem trochę w necie i doczytałem, że powinienem zamiast funkcji ROW_NUMBER() używać DENSE_RANK(). Okazuje się, że ROW_NUMBER() nadaje każdemu wierszowi kolejny, unikalny number. DENSE_RANK() nadaje unikalny numer ale jedynie wierszom, które się nie duplikują.

Na tej stronie możecie znaleźć fajnie to wszystko wyjaśnione. Również różnicę między DENSE_RANK() a RANK(). 
W skrócie:

  • ROW_NUMBER - nadaje każdemu wierszowi unikalny numer, nie zważając na duplikaty
  • RANK() - nadaje unikalnym wierszom rangę (unikalny numer) z przerwami w rankingu
  • DENSE_RANK() - nadaje unikalnym wierszom rangę (unikalny number) bez przerw w rankingu.  

Z tej powyższej strony wzięta jest również poniższa tabelka, która na szybko przedstawia różnicę między ROW_NUMBER(), RANK() oraz DENSE_RANK()
+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a |          1 |    1 |          1 |
| a |          2 |    1 |          1 |
| a |          3 |    1 |          1 |
| b |          4 |    4 |          2 |
| c |          5 |    5 |          3 |
| c |          6 |    5 |          3 |
| d |          7 |    7 |          4 |
| e |          8 |    8 |          5 |
+---+------------+------+------------+

wtorek, 15 kwietnia 2014

Asynchroniczne pobieranie danych i uaktualnianie CollectionView w WPF

W WPF klasa CollectionView jest niezwykle przydatna jeśli chcemy w prosty sposób zaimplementować mechanizm sortowania, grupowania lub filtrowania. Używając jej jednak w programowaniu asynchronicznym podczas uaktualniania tej kolekcji z innego wątku, dostaniemy następujący komunikat:

The calling thread cannot access this object because a different thread owns it

Nie dziwota, jest to normalnie zachowanie, które często się zdarza, ponieważ CollectionView nie obsługuje zmian własnej kolekcji z wątku innego niż Dispatcher. Co jednak zrobić aby obejść ten problem? Po pierwsze musimy mieć obiekt dispatcher'a, która w WPF'ie jest klasą zapewniającą usługi do zarządzania wątkami, np. synchronizacji. Jeśli korzystamy ze wzorca MVVM (Model-View-ViewModel), pierwsze co musimy zrobić to przekazać obiekt dispatcher'a do ViewModelu, np w konstruktorze:

private Dispatcher currentDispatcher;

public ViewModel(Dispatcher currentDispatcher)
{
    this.currentDispatcher = currentDispatcher;
}
Następnie aby dodawać obiekty do kolekcji CollectionViewSource, należy wykonać następujący kod:
currentDispatcher.Invoke(new Action(()=>
{
    this.collectionViewSource.Add(someObject);
}));

piątek, 11 kwietnia 2014

Database schema modeling - SQL Server Data Tools!

Post ku pamięci. Czy zdarzyło wam się kiedykolwiek, że mieliście 2 bazy danych, w których musieliście porównać ich schemę? Ja ostatnio miałem taką zagwozdkę, robiłem nową funkcjonalność i przepadł mi gdzieś skrypt, który uaktualniałby schemę bazy danych. Wiedziałem, że są pewne narzędzia, które by mi pomogły jednak nie chciałem korzystać z narzędzi firm trzecich. Poszperałem trochę w necie i okazało się, że Microsoft zrobił takie narzędzie. Nazywa się SQL Server Data Tools. Dzięki temu narzędzi możemy porównać sobie schemę dwóch baz, a nawet wygenerować skrypt zmian, który uaktualni nam naszą bazę danych.



SQL Server Data Tools jest dostarczane razem z Visual Studio 2013, jest możliwość dociągniecia instalki również do Visual Studio 2010 i Visual Studio 2012. Konkretną wersję można ściągnąć tutaj
http://blogs.technet.com/b/dataplatforminsider/archive/2013/11/13/microsoft-sql-server-data-tools-update.aspx

Co oferuje nam jeszcze to narzędzie? Możemy oczywiście graficznie modelować sobie naszą bazę danych. Mało tego narzędzie umożliwia nam nawet porównać dane w obu bazach za pomocą opcji "Data comparision" oraz tworzyć unit testy naszej bazy: więcej informacji znajdziemy tutaj