Materiały z mojej sesji na tegorocznym MTS’ie można znaleźć tutaj.
MTS 2012 – Materiały
NHibernate i query only property
Natrafiłem ostatnio na ciekawą i przydatną możliwość mapowania.
Wyobraźmy sobie następującą sytuację. Mamy dwie encje: Customer i Order.
public class Order { public int Id { get; set; } public decimal TotalPrice { get; set; } public Customer Customer { get; set; } } public class Customer { public int Id { get; set; } public string Name { get; set; } }
W strukturze obiektowej potrzebujemy tylko relację Order.Customer, natomiast nie chcemy mieć kolekcji Customer.Orders. Tylko jak teraz wybrać klientów, którzy nie mają zamówień?
Otóż da się to prosto uczynić wykorzystujac query only property. Zobaczmy na plik mapujący.
<class name="Order" table="Orders"> <id name="Id" column="Id"> <generator class="native"/> </id> <property name="TotalPrice" /> <many-to-one name="Customer" column="CustomerId" cascade="all" not-null="true"/> </class> <class name="Customer" table="Customers"> <id name="Id" column="Id"> <generator class="native"/> </id> <property name="Name" /> <bag name="Orders" access="none"> <key column="CustomerId" /> <one-to-many class="Order"/> </bag> </class>
Przy definicji mapowania kolekcji po stronie Customera używamy access=”none” albo access=”noop”. W naszym modelu ta relacja nie będzie widoczna, ale będzie mogli pisać zapytania przy jej użyciu. Poniższe wybieramy klientów, którzy mają co najmniej jedno zamówienia.
using (var s = sessionFactory.OpenSession()) { var customers = s.CreateQuery("from Customer c where size(c.Orders) > 0") .List(); foreach (var customer in customers) Console.WriteLine(customer.Name); }
Nowy artykuł o async i await właśnie się ukazał. Zapraszam do lektury.
“Długo oczekiwana funkcjonalność, która rozwiązuje problem, z jakim spotkał się każdy developer tworzący aplikację z GUI – blokowanie i zawieszanie się interfejsu użytkownika. Od teraz obsługa kontynuacji operacji asynchronicznych została wbudowana w sam język, co znacząco uprościło obsługę tego typu sytuacji.”
Zapraszam wszystkich na warsztaty poświęcone DDD i CqRS, które będę współprowadzić. Odbędzie się ono we Wrocławiu w najbliższym czasie. Więcej szczegółów oraz zapisy można znaleźć na następującej stronie.
MTS 2012 – moja sesja
Na zbliżającej się konferencji Microsoft Technology Summit 2012 będę miał przyjemność poprowadzić sesję na temat zaawansowanych technik DDD.
Będzie mowa o Bounded Contextach, o zdarzeniach domenowych, jak i o multilistenerach jakim są sagi.
Pełny abstrakt sesji to:
Jak naliczyć rabat w module sprzedażowym, jeśli w module CRM klient otrzymał statusu Gold? Jak po zatwierdzeniu zamówienia wysłać towar do klienta? A co w sytuacji, gdy naszym dobrym klientom wysyłamy towar natychmiast, a dopiero potem wystawiamy brakujące dokumenty? Podczas sesji zostaną przedstawione praktyczne techniki, które pozwalają budować autonomiczne moduły. Będą to zdarzenia domenowe oraz w przypadku bardziej nietrywialnych procesów biznesowych sagi.
W nowym wydaniu magazynu Programista można znaleźć mój artykuł o DSL w DDD, zapraszam do lektury.
Od pewnego czasu pracuję nad projektem demonstrujący kompleksowo wiele technik Domain Driven Design oraz Command Query Responsibility Segregation. Celem projektu jest:
- pokazanie wszystkich Building Blocków DDD
- pokazanie zaawansowanych technik DDD, np. Bounded Contexty i Sagi
- zaprezentowanie pragmatycznego podejścia do implementacji CqRS
- stworzenie bazy architektonicznej, na podstawie której można budować kolejne projekty
Natomiast plany na przyszłość, tą bliższą, jak i dalszą to:
- demostracja różnych technik testowania – UT, TDD, BDD, end-to-end
- wykorzystanie różnych form persystanecji: EF, NoSQL
- użycie EventSourcingu
- wykorzystanie NServiceBus jako implementacji szyny dla komend i zdarzeń
- integracja z telefonem (wp7, android), jak i autonomicznymi kontekstami napisanymi w Javie
Źródła projektu można znaleźć tutaj.
Natomiast wersja java, na której podstawie powstał projekt znajduje się tutaj.
Natrafiłem ostatnio na bardzo ciekawy zestaw czcionek. Otóż pozwalają one na tworzenie prostych grafik. Jak ona działa i wygląda można zobaczyć na poniższym filmie:
Szczegóły można znaleźć tutaj.
Tak to prawda. Ci co mnie znają, wiedzą o mojej negatywnej opinii o EF, a pozytywnej o NHibernate’ie.
Jednak ostatnio znalazłem bardzo przydatną funkcjonalność, tak naprawdę dowiedziałem się o jej braku w NHibernacie w porównaniu do EF. Otóż wyobraźmy sobie, że mamy zdefiniowaną poniższą metodę, która zwraca na IQueryable – interfejs, który pozwala na komponowanie zapytań linq i dopiero w momencie, gdy chcemy je wykonać, wszystko pakowane jest w jednego SQL i wysyłane do bazy.
public IQueryable<OrderDto> FindOrders() { var dto = from o in EntityManager.CurrentSession.Query<Order>() select new OrderDto (o.Id, o.TotalCost, o.SubmitDate, o.OrderStatus); return dto; }
Niestety poniższy kod nie działa w NHibernacie – funkcjonalność ta nie została nadal zaimplementowana…
Tylko niektóre operatory są supportowane w tym kontekście, np. Skip i Take.
var r = from dto in finder.FindOrders() where dto.OrderStatus == OrderStatus.Draft select dto; var result = r.ToArray();
Oczywiście w EF wszystko ładnie działa, zapytania się komponują i generują poprawne selecty.
C# pod lupą – params
Dzisiaj zajmiemy się kolejnym ciekawym dodatkiem w C# – słówkiem kluczowym params.
Do metody można przekazać kolekcję parametrów np. poprzez tablicę:
public string CombinePath(string[] parts) { return string.Join( "", parts ); }
Oczywiście użycie tej metody nie będzie bardzo komfortowe, gdyż trzeba zapisać tworzenie tablicy.
var path = CombinePath(new [] { "c:", "Window", "system32"});
Jeśli dodamy do naszego parametru słówko params (dostępne tylko na ostatnim parametrze), to będziemy mogli wykonywać funkcję jakby miała zmienną liczbę argumentów:
public string CombinePath(params string[] parts) { return string.Join( "", parts ); }
var path = CombinePath("c:", "Window", "system32");
Oczywiście nadal możemy przekazać tablice, np. poprzez kod infrastrukturalny.
Pamiętajmy, by następnym razem tworząc API uwzględnić ten syntactic sugar w adekwatnych miejscach, poprawiając czytelność kodu, jak i jego długość.