<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NHibernate &#8211; Strona Szoguna</title>
	<atom:link href="https://szogun1987.pl/show/tag/nhibernate/feed/" rel="self" type="application/rss+xml" />
	<link>https://szogun1987.pl</link>
	<description>Jeszcze wstawię tutaj jakiś głęboki cytat</description>
	<lastBuildDate>Sat, 25 Sep 2010 22:00:00 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.2</generator>
	<item>
		<title>Niestandardowe generowanie kluczy głównych w NHibernate</title>
		<link>https://szogun1987.pl/show/niestandardowe-generowanie-kluczy-glownych-w-nhibernate/6/</link>
		
		<dc:creator><![CDATA[szogun1987]]></dc:creator>
		<pubDate>Sat, 25 Sep 2010 22:00:00 +0000</pubDate>
				<category><![CDATA[C Sharp]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Programowanie]]></category>
		<guid isPermaLink="false">https://szogun1987.pl/?p=6</guid>

					<description><![CDATA[Robiąc ostatnio mały projekt postanowiłem w końcu wykorzystać NHibernate, na temat tego ORM'a jest w necie masa informacji więc nie będę się na jego temat rozpisywał. Podobnie nie ]]></description>
										<content:encoded><![CDATA[<p>Robiąc ostatnio mały projekt postanowiłem w końcu wykorzystać NHibernate, na temat tego ORM&#039;a jest w necie masa informacji więc nie będę się na jego temat rozpisywał. Podobnie nie będę opisywał konfiguratora Fluent NHibernate, kt&oacute;ry jest znacznie bardziej intuicyjny niż tradycyjne pliki hbm (oparte na XML).</p>
</p>
<p>Problemem przed jakim stanąłem był fakt że moja aplikacja miała wsp&oacute;łpracować z bazą na kt&oacute;rej działała inna aplikacja, posiadająca dosyć charakterystyczną politykę generowania kluczy gł&oacute;wnych. Kt&oacute;ra nijak nie pasowała do żadnej standardowej polityki zawartej standardowo w Bibliotece hibernate&#039;a.</p>
</p>
<p>Na szczęście NHibernate jest przygotowany na taką ewentualność, jego API zawiera interfejs IIDentifierGenerator, kt&oacute;ry umożliwia pisanie własnych polityk generowania kluczy. Interfejs ten zawiera jedną metodę Generate.</p>
<div class="code">
<pre class="prettyprint lang-cs">public class MyGenerator:IIDentiferGenerator
{
    public object Generate(ISessionImplementor session, Object obj)
   {
        return Guid.NewGuid()
    }
}</pre>
</div>
<p>Pierwszy parametr zapewnia dostęp do obiekt&oacute;w związanych z konfiguracją połączenia z bazą danych oraz stanem tego połączenia, drugim parametrem jest obiekt dla kt&oacute;rego generowany jest klucz. Przykład powyżej dla każdego obiektu zwr&oacute;ci wartość statycznej metody NewGuid kt&oacute;ra nadaje się na klucz gł&oacute;wny ponieważ z definicji jest to Global Unique Identifier. Jednak generowanie nowego Guida nie jest niczym nadzwyczajnym po za tym biblioteka NHibernate&#039;a już ją zawiera.</p>
<p>Częstym sposobem generowania kluczy gł&oacute;wnych jest procedura składowana (lub fragment zapytania SQL) kt&oacute;ra zwraca najniższą nieużywaną wartość kt&oacute;rą aplikacja może wykorzystać jako klucz dla danej tabeli.</p>
<p>Aby uruchomić takie zapytanie pod kontrolą NHibernate należy wykorzystać właściwości Connection i Batcher parametru session przekazanego do metody generate.</p>
<div class="code">
<pre class="prettyprint lang-cs">public class MyGenerator:IIDentiferGenerator
{
    public object Generate(ISessionImplementor session, Object obj)
   {
        using(IDbCommand command = session.Connection.GenerateCommand())
        {
            command.CommandText = &quot;exec GetNextId()&quot;;
            using(IDataReader  reader = session.Batcher.ExecuteReader())
            {
                if (reader.Read())
                {
                     return reader.GetInt(0);
                }
                else
                {
                      throw new Exception (&quot;Nie da się wygenerować klucza.&quot;);
                }
            }
        }
    }
}</pre>
</div>
<p>Klasa przedstawiona powyżej jedną poważną wadę: jest bardzo sztywna tj. trudno byłoby ją wykorzystać do generowania klucza dla dowolnej encji. Informację na temat tabeli w kt&oacute;rej należy sprawdzać &quot;Zajętość&quot; danego identyfikatora można uzyskać tylko przez weryfikację typu parametru obj metody Generate. Wykorzystanie tego faktu sprawiłoby to że programista musiałby dla każdego obsługiwanego typu dopisywać kilka linijek kodu w tej metodzie co generowałoby masę powtarzalnego kodu.</p>
<p>Znacznie lepszym rozwiązaniem jest Implementacja Interfejsu IConfigurable zawierającego metodę Configure kt&oacute;ra przyjmuje jako parametry następujące wartości:</p>
<p>type &#8211; typ dla jakiego jest konfigurowana klasa</p>
<p>params &#8211; Słownik klucz &lt;=&gt; wartość przechowujący dodatkowe dane konfiguracyjne.</p>
<p>d &#8211; informacja na temat silnika bazodanowego przechowującego dane.</p>
<p>Parametrem nas interesującym jest params zawiera on dane na temat tabeli w kt&oacute;rej zapisywany jest dany typ oraz kolumny będącej kluczem gł&oacute;wnym. Nie jestem pewien czy dla każdego silnika bazodanowego nazwy kluczy są takie same dlatego nie podaję tutaj konkretnego fragmentu kodu.</p>
</p>
<p>Pozostaje jeszcze tylko kwestia jak powiedzieć NHibernate&#039;owi żeby dla danej klasy używał naszego generatora. We FluentHibernate wymaga to wpisania jednej linijki w klasie Mapującej:</p>
<div class="code">
<pre class="prettyprint lang-cs">Id(obj =&gt; obj.ID).GeneratedBy().Custom&lt;MyGenerator&gt;()
</pre>
</div>
<p>Edit: 02-10-2010</p>
<p>Podczas prac w NHibernate zauważyłem że zachowuje się on dosyć specyficznie podczas zapisu więcej niż jednego obiektu jedego typu w ciągu jednej tranzakcji. Ot&oacute;ż najpierw generuje on klucze gł&oacute;wne dla wszystkich nowych obiekt&oacute;w, a następnie dokonuje ich zapisu. Jeżeli teraz oprzemy nasz mechanizm zapisu na zapytaniu do bazy to musimy się liczyć z faktem iż za każdym razem generowanie klucza będzie się odbywać na niezmienionej bazie. Więc zapytanie wywołane za każdym razem zwr&oacute;ci tą samą wartość. Należy to uwzględnić w kodzie, najczęściej przez duplikację części logiki zapytania, co jest oczywistą wadą tego rozwiązania, zaletą jego zaś jest mniejsza ilość zapytań co zazwyczaj poprawia aplikację pod względem wydajnosciowym.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
