Przygody z oprogramowaniem
  • Start
  • Szkolenia
    • Szkolenia otwarte
    • Katalog szkoleń
  • Usługi
    • Konsulting
    • Mentoring
    • Research & Development
  • Blog
  • Wiedza
    • Strefa wiedzy
    • BFsharp
    • SaaS
  • Klienci
  • Kontakt
0

NHibernate i query only property

12 October, 2012-C#, NHibernate

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);
}
Czytaj dalej | Dyskutuj
2

W czym EntityFramework jest lepsze od NHibernate?

6 August, 2012-EntityFramework, Linq, NHibernate

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.

Czytaj dalej | Dyskutuj

Kategorie

Architecture BFsharp Blog Business Framework C# CqRS DDD Debugging DSL EntityFramework Formula JavaScript Linq NHibernate SaaS Silverlight SQL Visual Studio WPF Wzorce

O mnie


RSS Feed

© macmichal.pl 2011 Wszystkie prawa zastrzeżone