sobota, 28 września 2013

nHibernate - początki

Do ORM nHibernate podchodziłem już kilkakrotnie. Może wynikało to ze względu na to, że całą konfigurację wykonywało się w XML, a może to że nie wspierał w pełni LINQ.
Od czasów kiedy chciałem się nim zająć wiele się zmieniło w tej kwestii i obecnie wersja 3.3 zapewnia bardzo wiele z tego, co kiedyś wydawało się niemożliwe.
Parę faktów:
Aby rozpocząć korzystanie z biblioteki należy pobrać albo z sourceforge spakowane binarki, albo za pomocą NuGet-a ściągnąć pliki do projektu:



Po dodaniu referencji do biblioteki warto dodać pliki schemy, aby ułatwić sobie pisanie mappingów. W tym celu dodajemy do solucji folder Schema i wrzucamy do niego pliki schemy udostępnione wraz z nHibernate:


Aby pliki mapowania mogły działać i podpowiadać składnię w Visual Studio, należy je dodać do obsługiwanych plików schemy. Aby to zrobić wchodzimy w którykolwiek plik ze schemą, w meni XML wybieramy opcję XML->Schemas... i wskazujemy miejsce gdzie znajdują się pliki:


Teraz możemy napisać pierwsze mapowanie. W celach pokazowych posłużę się bazą MS SQL 2012 AdventureWorksLT2012. W bazie tej zawarta jest tabela ProductDescription do której stworzę przykładowe mapowanie. 

Najpierw stworzymy klasę która odpowiada tabeli w bazie danych:



Code:
using System;

namespace nHibernateCreatingMapping.Domain
{
 public class ProductDescription
 {
  public virtual int ProductDescriptionID { get; protected set; }
  public virtual string Description { get; set; }
  public virtual Guid Rowguid { get; protected set; }
  public virtual DateTime ModifiedDate { get; set; }
 }
}

Teraz stworzymy plik mapujący klasę do tabeli w bazie danych:


Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="nHibernateCreatingMapping" namespace="nHibernateCreatingMapping.Domain">
  <class name="ProductDescription" table="SalesLT.ProductDescription">
    <id name="ProductDescriptionID">
      <generator class="identity" />
    </id>
    <property name="Description" />
    <property name="Rowguid" />
    <property name="ModifiedDate" />
  </class>
</hibernate-mapping>


Bardzo ważne: w właściwościach pliku z mapowaniem należy ustawić parametr Build Action na Embedded Resource (o innych możliwościach napiszę w osobnym poście).

Kolejną czynnością będzie dodanie konfiguracji do app.config w celu ustawienia podstawowych opcji nHibernate:


Code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
  </configSections>
  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory>
      <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.connection_string">Server=localhost;initial catalog=AdventureWorksLT2012;Integrated Security=True</property>
      <mapping assembly="nHibernateCreatingMapping" />
    </session-factory>
  </hibernate-configuration>
  <connectionStrings>
    <add name="AdventureWorks" connectionString="Data Source=localhost;Integrated Security=true;Initial Catalog=AdventureWorksLT2012" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>    
</configuration>


Po ustawieniu wszystkich parametrów możemy przystąpić do tworzenia sesji nHibernate i odpytywania bazy danych:


Code:
            ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
            var session = sessionFactory.OpenSession();
            var productDescriptions =
                session.Query<ProductDescription>()
                    .Where(x => x.ProductDescriptionID > 10 && x.ProductDescriptionID < 100);
            foreach (var productDescription in productDescriptions)
            {
                Console.WriteLine("{0} {1} {2}", productDescription.ProductDescriptionID,
                    productDescription.ModifiedDate, productDescription.Description);
            }

Rezultat:



W kolejnych opiszę dokładniej mechanizmy rządzące nHibernate, bardziej zaawansowane przypadki mapowania i inne ciekawe aspekty tej biblioteki.

1 komentarz: