<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8254280458207814344</id><updated>2012-01-10T20:00:33.238+01:00</updated><category term='C#'/><category term='nHibernate'/><category term='Visual Studio'/><category term='Css'/><category term='MVC'/><category term='Web Api'/><category term='SQL'/><category term='Linq'/><category term='REST'/><category term='Wzorce projektowe'/><category term='Wszystko i nic'/><category term='Narzędzia'/><category term='Events'/><category term='IIS'/><category term='Beginning'/><category term='Entity Framework'/><category term='ASP.NET'/><title type='text'>Programistka i kot</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3054949108406464519</id><published>2011-10-15T18:54:00.000+02:00</published><updated>2011-10-15T18:54:00.762+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>ABB Dev Day 2011</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-UWQ4XplknHQ/TpimqzGJRiI/AAAAAAAAAQY/EG_CHFey5Ug/s1600/abb2.png"&gt;&lt;img style="float:left; margin:5 10px 10px 5;  cursor:pointer; cursor:hand;width: 255px; height: 63px;" src="http://3.bp.blogspot.com/-UWQ4XplknHQ/TpimqzGJRiI/AAAAAAAAAQY/EG_CHFey5Ug/s400/abb2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5663459785619097122" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abb.pl/cawp/plabb045/b0e290849d57794bc1257902002ad411.aspx"&gt;&lt;img style="float:left; margin:5px auto 10px; text-align:center; cursor:pointer; cursor:hand;width: 400px; height: 252px;" src="http://4.bp.blogspot.com/-H6SZh4CoOYc/TpimDAh94cI/AAAAAAAAAQM/8sHshVlUIrQ/s400/abb1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5663459102030684610" /&gt;&lt;/a&gt;
Po prostu kolejna konferencja?&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
Moim zdaniem niekoniecznie. &lt;span style="font-weight:bold;"&gt;Poziom, tempo, organizacja ale przede wszystkim tematy prezentacji i charyzmatyczni prelegenci...&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;
Ja się zawsze zachwycam darmowymi konferencjami więc może tylko powiem że nawet nie mam nadziei że MTS będzie równie dobry.
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;span class="fullpost"&gt;
Konferencja nie była taka bardzo techniczna, były sesje w których nie było ani linijki kodu. Jednak uważam że takich właśnie wydarzeń brakuje, tak charyzmatycznych ludzi słuchamy zbyt rzadko. I na taką właśnie powtórkę będę czekać z utęsknieniem w przyszłym roku.
&lt;br/&gt;&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Organizacja&lt;/span&gt;&lt;br/&gt;
Podobała mi się strona konferencji, krótko i na temat, znalazłam nawet info o parkowaniu (tego mi było trzeba). Strona i rejestracja zrobiła przy okazji na mnie wrażenie mniej bezdusznej niż każda tego typu. Może to szczegół ale miły.&lt;br/&gt;
Ciekawym pomysłem było zrezygnowanie z obiadu. Oczywiście trzeba mieć dobrą lokalizację aby było gdzie iść coś upolować, ale dzięki temu nie zgubiła się atmosfera spotkania przy kawie (i jakże zajebiście wyśmienitym cieście). &lt;br/&gt;
&lt;br/&gt;
&lt;a href="http://www.abb.pl/cawp/plabb045/c3ef4f9cd35e8dcec125790200305ba3.aspx"&gt;&lt;span style="font-weight:bold;"&gt;Agenda&lt;/span&gt;&lt;/a&gt;&lt;br/&gt;
Słowem wstępu&lt;br/&gt;
Co to jest ABB, skąd się wzięło i czym się zajmuje? To pierwsze charyzmatyczne wystąpienia tego dnia. Aż strach pomyśleć iloma zabawkami ta firma dysponuje. Przemysł elektryczny i jego wsparcie to tylko początek, później pomyśleć o wszystkim co po drodze do gwiazd i już lądujemy na Marsie gdzie ABB również będzie w projekcie badawczym... oj ta pamięć nie wiem co będą badać ale czy to ważne w skali kosmosu ;)&lt;br/&gt;
Była też mowa o Krakowskim centrum badawczym (również tym czysto informatycznym)

&lt;br/&gt;&lt;br/&gt;
Tiberiu Covaci&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Patterns for Parallel Programming
&lt;/span&gt;&lt;br/&gt;
Programowanie równoległe, taski i podział zadań. Genialnie prosty przykład z gotowaniem. No bo kto głodny nie chciałby przyspieszyć finału gotowania :) innymi słowy warto stosować programowanie równoległe. Na przykładzie krojenia i obierania dowiadujemy się o dekompozycji tasków, paralelizacji dostępu do danych algorytmach no i w końcu narzędziach &lt;span style="color:blue;"&gt;Task&lt;/span&gt; i &lt;span style="color:blue;"&gt;Paraller&lt;/span&gt;. &lt;br/&gt;
Prostota przykładu + charyzmatyczny Tibi = pierwsza rewelacyjna sesja 

&lt;br/&gt;&lt;br/&gt;
Szymon Pobiega&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;REST and CQRS: combining two sexy architectures in one awesome solution&lt;/span&gt;&lt;br/&gt;
Trochę o REST potem trochę o CQRS - fajnie i prosto, tak aby szybko załapać (tak jak mi brakowało gdy startowałam z RESTem). A potem z najlepszych elementów obu architektur Szymon stworzył CQREST. Trochę radosnej twórczości a na koniec wyzwanie - architektura nie ma swojej implementacji, Szymon czeka dwa tygodnie na materializacje swojej wizji.&lt;br/&gt;
Musze przyznać że Pex dawał czadu prezentując płynnie przejścia i powiązania między elementami architektury. Odbiór prezentacji z sali wydawał się negatywny, programiści martwili się co i jak zaimplementować i czy nie będzie to kilkukrotna robota. No cóż w końcu wyszliśmy z założenia że w CQRS szyny (BUS) są bardzo drogie i niełatwe w utrzymaniu, aby je zastąpić będzie trzeba się troszkę pomęczyć.&lt;br/&gt;
Miło było zobaczyć wizję czegoś od drugiej strony - bez wymagań bez zastosowań. Ciekawe czy wyzwanie zostanie podjęte.
&lt;br/&gt;&lt;br/&gt;

Michał Brzozowski&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Wprowadzenie do zasad SOLID - czyli jak pisać SOLIDny kod&lt;/span&gt;&lt;br/&gt;
Byłam kiedyś już na sesji z tego zagadnienia i przez tamto wrażenie nie miałam ochoty iść ponownie. Bo czego nowego możemy się dowiedzieć o pisaniu solidnego kodu... Nawet jeśli znamy zasady i wydaje nam się że je stosujemy to myślę że nawet przed sobą nie chcemy się przyznać że tak nie jest. &lt;br/&gt;
Kolejna charyzmatyczna prezentacja i dużo przykładów z życia skwitowane manifestem Craftsmanship over &lt;strike&gt;Crap&lt;/strike&gt; Execution.&lt;br/&gt;
Wydźwięk sesji był taki jakie ja wrażenie wyniosłam z całej konferencji - skupiamy się na technologiach zapominając że tworzymy skomplikowane systemy, które muszą być dobrze zaprojektowane, przemyślane.&lt;br/&gt;
I jeszcze jedno hasło które przypadło mi do gustu&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;KISS - Keep it simple, stupid!&lt;/span&gt;
&lt;br/&gt;&lt;br/&gt;
Jakub Kaprzyk&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Bezpieczeństwo aplikacji webowych na przykładzie ASP.NET MVC&lt;/span&gt;&lt;br/&gt;
Ciekawy temat, fajnie że Jakub pokazał jak banalnie proste jest 'zepsucie' niezabezpieczonej właściwie strony. Niestety czasu było mało i omówione zostały tylko trzy najczęstsze błędy w zabezpieczeniach. Temat naprawdę zaszedł mi za skórę, pomimo walki z poobiednim zmęczeniem, trzeba będzie kiedyś zajrzeć na stronę &lt;span style="font-style:italic;"&gt;Open Web Application Security Project &lt;/span&gt;i zagłębić się w błędy i wskazówki jak ich unikać.
&lt;br/&gt;&lt;br/&gt;
Paweł Brodziński&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Visual Menagement, czyli jak prostymi metodami poprawić przepływ informacji i organizacji pracy&lt;/span&gt;&lt;br/&gt;
Zacznijmy prosto. Weźmy tablicę, kolorowe markery, kolorowe karteczki i magnesy. Pobawmy się tymi najbardziej elastycznymi i skalowalnymi narzędziami. Dużo pomysłów co można osiągnąć, jak wykorzystać proste narzędzia, jak usprawnić komunikacje. Część rzeczy bardzo mi się podobała - pełen obraz sytuacji w zespole to element którego często brakuje. Jednak niewiele tak naprawdę obecnie jetem w stanie wykorzystać z tych pomysłów przy pracy w bardzo rozproszonym zespole. A z poprzednich prac mam doświadczenie jak trudno wprowadza się zmiany typu rusz tyłek - bo trzeba podejść do tablicy i coś zmienić (a ja przez 3 lata próbowałam nakłonić zespół do pisania komentarzy do checkinów...)&lt;br/&gt;
&lt;a href="http://www.slideshare.net/pawelbrodzinski/visual-management"&gt;Tutaj link do prezentacji.&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
Rob Ashton&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Modelling documents for data access&lt;/span&gt;&lt;br/&gt;
Emmm... ee? wow
&lt;br/&gt;&lt;br/&gt;
To tyle wrażeń. Jedno co zapamiętałam to: Conflict + size - wyznaczniki co powinno iść do danego obiektu. &lt;Br/&gt;
Ale o co kurde chodzi... Po wyjściu z sali słyszałam głosy że przydał by się wstęp po co to coś w ogóle jest i podpisuje się pod tymi głosami. Może tylko zbyt do tyłu jestem. Może kiedyś to do mnie dotrze ;)&lt;br/&gt;

&lt;br/&gt;&lt;br/&gt;
Mam nadzieje że kolejna edycja się odbędzie i że poziom i tematyka zostaną zachowane.
&lt;br/&gt;
Było super, oby tak dalej.





&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3054949108406464519?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3054949108406464519/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3054949108406464519&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3054949108406464519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3054949108406464519'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/10/abb-dev-day-2011.html' title='ABB Dev Day 2011'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-UWQ4XplknHQ/TpimqzGJRiI/AAAAAAAAAQY/EG_CHFey5Ug/s72-c/abb2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3986624831641061212</id><published>2011-09-17T00:20:00.001+02:00</published><updated>2011-09-17T00:20:31.530+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wszystko i nic'/><title type='text'>Windows 8 Developer Preview</title><content type='html'>Dziś kończy się konferencja &lt;a href="http://www.buildwindows.com/"&gt;&lt;span style="font-weight:bold;"&gt;Build&lt;/span&gt;&lt;/a&gt;, nawet nazwa konferencji jest nowa, jak  i większość zaprezentowanych na konferencji produktów. Od razu pierwszego dnia zaprezentowano Windows8 Developer Preview a parę godzin później można było go pobrać i zobaczyć na własne oczy.&lt;br/&gt;
Co też uczyniłam :]
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Instalacja na VirtualBoxie była bezproblemowa i nawet dość szybka. Później troszkę się zirytowałam gdy nie dało się doinstalować toolsów Virtualboxa co oznacza ograniczenie rozdzielczości, urządzeń i przechwytywania myszy. &lt;br/&gt;
Zachęcona wizją SkyDriva wybrałam LiveID do logowania i to jest akurat opcja która mi się wyjątkowo podoba z samego założenia, jednak dostać się do plików przechowywanych na SkyDrive jakoś mi się jeszcze nie udało. (&lt;a href="http://db.tt/GKmnplk"&gt;DropBox &lt;/a&gt;nadal niepokonany)&lt;br/&gt;
Ale zacznijmy od początku czyli menu?dashboard?screen Start
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-vJ31U1BcutE/TnOV9eJVDoI/AAAAAAAAAPg/tyftMAO4KpE/s1600/w8_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 298px;" src="http://4.bp.blogspot.com/-vJ31U1BcutE/TnOV9eJVDoI/AAAAAAAAAPg/tyftMAO4KpE/s400/w8_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5653026840576855682" /&gt;&lt;/a&gt;
&lt;br/&gt;
Jedne kafelki są statyczne - jak te do otwierania aplikacji, inne są mniej więcej żywe - RSSy, pogoda, socialite, email - wyświetlają aktualne dane.
&lt;br/&gt;&lt;br/&gt;
Teoria: Start to miejsce skąd odpala się programy, przełącza pomiędzy uruchomionymi programami oraz gdzie znajdują się wszelkie gadżety i notyfikacje i jest w pełni kustomizowalne&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-TqUr5NKX0IY/TnOwLo5FORI/AAAAAAAAAP4/RP-lW2K5YVw/s1600/w8_igoo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 309px;" src="http://1.bp.blogspot.com/-TqUr5NKX0IY/TnOwLo5FORI/AAAAAAAAAP4/RP-lW2K5YVw/s400/w8_igoo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5653055671281989906" /&gt;&lt;/a&gt;
Od kilku lat używam iGoogla jako takiego miejsca startowego - mam pogodę, RSSy, miejsce na notatki, kalendarz, pocztę, komunikator, możliwość dodawania gadżetów i co ważne bardzo elastyczną kustomizacje. Brzmi znajomo :] &lt;br/&gt;
Od ekranu startowego iGoogla jednak różni wiele - nie można startować ani przełączać programów, ale zarządzanie treścią jest zdecydowanie przyjemniejsze jak dla mnie.&lt;br/&gt; Cóż może ten ekran zostanie jeszcze udoskonalony w kolejnych kompilacjach Windows 8.&lt;br/&gt; 
&lt;br/&gt;
Wróć do użytkowania Start w Windows 8 zgodnie z teorią.&lt;br/&gt;
Hmm tak w pełni pozmieniać wygląd do własnych wymagań to mi się nie udało. Startować aplikacje.. no ok, przełączanie - jakoś osobiście mi to nie odpowiada bo tak naprawdę nie wiadomo co jest uruchomione a co nie.&lt;br/&gt;
No właśnie co jest uruchomione. To jest fascynujące i nie rozgryzłam tego jeszcze.&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-6mgYLDovsJE/TnOl7LJ-MfI/AAAAAAAAAPo/IY981pJs_oY/s1600/altTab.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 103px;" src="http://4.bp.blogspot.com/-6mgYLDovsJE/TnOl7LJ-MfI/AAAAAAAAAPo/IY981pJs_oY/s400/altTab.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5653044393305584114" /&gt;&lt;/a&gt;
Według starego dobrego AltTab mam otwarte IE w wersji metro, IE w wersji desktop (to akurat mi się podoba że jest podział choć zaskoczyło mnie to), pogodę, socialite (swoją drogą ciekawe czy będzie możliwość wybierania spoleczności czy też pozostanie 'jedyny właściwy')[sory za zdjęcia ;)], i jakiś katalog.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-cCVpTzcwTEM/TnOmApq5CUI/AAAAAAAAAPw/t1sfHQ5wVYU/s1600/tm1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 364px;" src="http://1.bp.blogspot.com/-cCVpTzcwTEM/TnOmApq5CUI/AAAAAAAAAPw/t1sfHQ5wVYU/s400/tm1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5653044487396067650" /&gt;&lt;/a&gt;
Pomijając Painta, którego otworzyłam później śliczny nowy TaskManager mówi mi że metro IE oraz socialite są 'suspended' czyli że nie obciążają procesora, oszczędzają energię... Ok ale mam też zawieszone Alarms i pomimo tego zawieszenia - alarmy (notyfikacje) się pojawiają hmmm. Alarmy też nie pokazały się w altTab. Podobnie jest z moją ulubioną grą WordHunt nie pokazuje się w TaskManagerze, natomiast jest w altTab... Troszkę nie potrafię się znaleźć co żyje i gdzie i kiedy - a niby była gadka o posiadaniu kontroli nad systemem a nie byciu kontrolowanym przez system :]&lt;br/&gt;
Moją największą bolączką jest jednak... zamykanie aplikacji metro. Po prostu nie potrafię znaleźć takiej opcji. Cóż nie jest to aż tak intuicyjne *chyba.
&lt;br/&gt;
Suspendują się chyba tylko aplikacje metro, ponieważ zwyczajny IE jedzie po procesorze całkiem normalnie.&lt;br/&gt;

&lt;br/&gt;
&lt;br/&gt;
Drugiego dnia konferencji w motywacyjnej mowie Steve Ballmer ogłosił że Windows 7 osiągnął 450 milionów sprzedanych egzemplarzy (jeśli dobrze pamiętam) po raz pierwszy tym samym przewyższając XP w udziałach w rynku.&lt;br/&gt;
Z jednej strony Windows 8 ma szansę szybciej rosnąć w liczbach ze względu na tablety i zapewnić możliwości programistom budowania ciekawych aplikacji. Z drugiej strony patrząc po obecnych wymaganiach klientów, zwłaszcza klientów z polskich urzędów... Cóż mam wrażenie ze ekran startowy w tym wypadku może być dodatkową bronią obosieczną skierowaną w programistów - z jednej strony pozostaną stare przyzwyczajenia użytkowników a z drugiej - świetne nowe miejsce do marnotrawienia czasu pracy (oczywiście zakładając że już będą posiadaczami 8).&lt;br/&gt;
&lt;br/&gt;
Windows 8 ma zapewne jeszcze dużo ciekawostek, spędziłam z nim dopiero 3 dni. Niebawem zaczną pojawiać się  kolejne sesje z Build'a - kolejne nowości i wyzwania. A ja jakoś po keynotes i po artykule &lt;a href="http://mmulawa.blogspot.com/2011/09/statystyczny-programista-net-ad-2011.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+BlogMaksymilianaMulawy+%28Blog+Maksymiliana+Mulawy%29"&gt;Statystystyczny programista&lt;/a&gt; nie mogę się pozbyć wrażenia że umieć trzeba po prostu wszystko, być na bieżąco z nowościami i potrafić się cofnąć do technik kodowania sprzed 15 lat... tylko kto jest w stanie spać aż tak mało?&lt;br/&gt; 
 
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3986624831641061212?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3986624831641061212/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3986624831641061212&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3986624831641061212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3986624831641061212'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/09/windows-8-developer-preview.html' title='Windows 8 Developer Preview'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-vJ31U1BcutE/TnOV9eJVDoI/AAAAAAAAAPg/tyftMAO4KpE/s72-c/w8_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-218257826781543260</id><published>2011-08-18T23:13:00.008+02:00</published><updated>2011-08-18T23:13:01.032+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Api'/><title type='text'>5. WCF Web Api - consuming simple Get service</title><content type='html'>Coś na ząb ;) &lt;b&gt;Skonsumujmy prosty serwis Web Api&lt;/b&gt;
Poprzednio:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/1-rest-small-introduction.html"&gt;1. REST - small introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/2-wcf-web-api-linkownia.html"&gt;2. WCF Web Api - linkownia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/08/3-wcf-web-api-szybki-start.html"&gt;3. WCF Web Api - szybki start&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/08/4-wcf-web-api-simple-get.html"&gt;4. WCF Web Api - simple GET&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;br/&gt;
Rest = zasób + reprezentacja. &lt;br/&gt;
Ostatnio stworzyłam zasób, ale nie było mowy o reprezentacji.&lt;br/&gt;
&lt;span class="fullpost"&gt;
Kiedy próbowałam napisać coś restful w WCFie irytowało mnie że w pewnym momencie trzeba było podać JSON czy XML. Być może wtedy nie wnikałam wystarczająco głęboko ;)&lt;br/&gt;
W Web Api nic żeśmy nie określali a przeglądarka od razu potrafiła odczytać XML.&lt;br/&gt;
Posługując się &lt;a href="http://www.fiddler2.com/fiddler2/"&gt;Fiddlerem&lt;/a&gt; łatwo jest pokazać jak uzyskać XML albo JSONa.&lt;br/&gt;
XML (domyślnie):
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-0yShJdadVWI/Ti8y05vhzLI/AAAAAAAAAPA/fvK1yiJoaj0/s1600/webapi5_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 304px;" src="http://2.bp.blogspot.com/-0yShJdadVWI/Ti8y05vhzLI/AAAAAAAAAPA/fvK1yiJoaj0/s400/webapi5_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633777543298534578" /&gt;&lt;/a&gt;
Wynik:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-3W7IVlLahyQ/Ti8y6YlNM6I/AAAAAAAAAPI/Nh1PUeuogLo/s1600/webapi5_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 304px;" src="http://4.bp.blogspot.com/-3W7IVlLahyQ/Ti8y6YlNM6I/AAAAAAAAAPI/Nh1PUeuogLo/s400/webapi5_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633777637476086690" /&gt;&lt;/a&gt;

&lt;br/&gt;
JSON - wystarczy podać &lt;span style="font-weight:bold;"&gt;Accept: application/json&lt;/span&gt; aby dostać wyniki w formacie Json 
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-Y_858nFjgdI/Ti80qqho4eI/AAAAAAAAAPQ/7TmFArS62dw/s1600/webapi5_3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 304px;" src="http://4.bp.blogspot.com/-Y_858nFjgdI/Ti80qqho4eI/AAAAAAAAAPQ/7TmFArS62dw/s400/webapi5_3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633779566438310370" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-wegWPZEnS6A/Ti80uJhIQNI/AAAAAAAAAPY/tut20fXA3wY/s1600/webapi5_4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 304px;" src="http://2.bp.blogspot.com/-wegWPZEnS6A/Ti80uJhIQNI/AAAAAAAAAPY/tut20fXA3wY/s400/webapi5_4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633779626297278674" /&gt;&lt;/a&gt;
I to jest to co dostajemy z pudełka - o ile nie mamy żadnych bardziej skomplikowanych danych jak choćby obrazków (to potem).&lt;br/&gt;
&lt;br/&gt;
Web Api udostępnia również klasę klienta rest: &lt;span style="color:blue;"&gt;HttpClient&lt;/span&gt; &lt;br/&gt;
Najprostszy przypadek Xml:
&lt;pre name="code" class="brush:c-sharp;"&gt;
HttpClient httpClient = new HttpClient();
HttpResponseMessage res = httpClient.Get("http://localhost/WebApiTests/api/contacts");
if (res.StatusCode == System.Net.HttpStatusCode.OK)
{
     textBox1.Text += res.Content.ReadAsString();
     //jakoś wole TextBoxy w WinFormsach niż aplikacje konsolowe
}
else
{
     // w razie niepowodzenia wypisz tylko status 
     textBox1.Text += res.StatusCode.ToString();
}
&lt;/pre&gt;
Output:
 &lt;div style="color:black;overflow:auto;width:99.5%;"&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;?&lt;span style="color:#a31515"&gt;xml&lt;span style="color:#0000ff"&gt; &lt;span style="color:#ff0000"&gt;version&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&lt;span style="color:#000000"&gt; &amp;quot;&lt;span style="color:#0000ff"&gt;1.0&lt;/span&gt;&lt;span style="color:#000000"&gt; &amp;quot;&lt;span style="color:#0000ff"&gt; &lt;span style="color:#ff0000"&gt;encoding&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&lt;span style="color:#000000"&gt; &amp;quot;&lt;span style="color:#0000ff"&gt;utf-8&lt;/span&gt;&lt;span style="color:#000000"&gt; &amp;quot;&lt;span style="color:#0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;span style="color:#a31515"&gt;ArrayOfContact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;  &amp;lt;&lt;span style="color:#a31515"&gt;Contact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;    &amp;lt;&lt;span style="color:#a31515"&gt;ContactId&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; 1&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;span style="color:#a31515"&gt;ContactId&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;    &amp;lt;&lt;span style="color:#a31515"&gt;Name&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; Glenn Block&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;span style="color:#a31515"&gt;Name&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;  &amp;lt;/&lt;span style="color:#a31515"&gt;Contact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;  &amp;lt;&lt;span style="color:#a31515"&gt;Contact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;    &amp;lt;&lt;span style="color:#a31515"&gt;ContactId&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; 2&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;span style="color:#a31515"&gt;ContactId&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;    &amp;lt;&lt;span style="color:#a31515"&gt;Name&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; Howard Dierking&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;span style="color:#a31515"&gt;Name&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;  &amp;lt;/&lt;span style="color:#a31515"&gt;Contact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000"&gt; &lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;span style="color:#a31515"&gt;ArrayOfContact&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/pre&gt;
&lt;pre style="margin:0em;"&gt; &lt;/pre&gt;
&lt;/div&gt;


Z Jsonem jest troszkę trudniej bo trzeba przekazać informację że chcemy jsona do wywołania serwisu.
&lt;pre name="code" class="brush:c-sharp;"&gt;
HttpClient httpClient = new HttpClient();

var request = new HttpRequestMessage()
{
    Method = HttpMethod.Get,
    RequestUri = new Uri("http://localhost/WebApiTests/api/contacts")
};
//Dodajemy dokładnie to samo co w Fiddlerze - "Accept"
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage responseJason = null;
responseJason = httpClient.Send(request, HttpCompletionOption.ResponseHeadersRead);

if (responseJason != null)
{
    if (responseJason.StatusCode == System.Net.HttpStatusCode.OK)
    {
        textBox1.Text += responseJason.Content.ReadAsString();
    }
    else
    {
        textBox1.Text += responseJason.StatusCode.ToString();
    }
}
/*Output:
 [{"ContactId":1,"Name":"Glenn Block"},{"ContactId":2,"Name":"Howard Dierking"}]
 */
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-218257826781543260?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/218257826781543260/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=218257826781543260&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/218257826781543260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/218257826781543260'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/08/5-wcf-web-api-consuming-simple-get.html' title='5. WCF Web Api - consuming simple Get service'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-0yShJdadVWI/Ti8y05vhzLI/AAAAAAAAAPA/fvK1yiJoaj0/s72-c/webapi5_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-6064556747359805498</id><published>2011-08-04T23:59:00.000+02:00</published><updated>2011-08-04T23:59:01.122+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Api'/><title type='text'>4. WCF Web Api - simple GET</title><content type='html'>&lt;b&gt;  &lt;/b&gt;
Bardzo prosty przykład pobrania danych. Prosty przykład na prostych danych czyli standardowo mamy stringa i inta. Sama nienawidzę takich przykładów bo jeśli cokolwiek dołożymy przestają działać. Bez obaw - dokładać będziemy później. &lt;br/&gt;&lt;br/&gt;
Poprzednio :
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/1-rest-small-introduction.html"&gt;1. REST - small introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/2-wcf-web-api-linkownia.html"&gt;2. WCF Web Api - linkownia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/08/3-wcf-web-api-szybki-start.html"&gt;3. WCF Web Api - szybki start&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;br/&gt;
&lt;span class="fullpost"&gt;
Mamy tylko 3 miejsca gdzie musimy coś napisać 
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-6_8zQOJKxE0/Ti2J-QDmoSI/AAAAAAAAAOg/fIIGs3_-tvk/s1600/WebApi4_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 161px; height: 400px;" src="http://3.bp.blogspot.com/-6_8zQOJKxE0/Ti2J-QDmoSI/AAAAAAAAAOg/fIIGs3_-tvk/s400/WebApi4_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633310411465335074" /&gt;&lt;/a&gt;
Moja przykładowa klasa Contact czy Resource
&lt;pre name="code" class="brush:c-sharp;"&gt;
 public class Contact
    {
        public int ContactId { get; set; }
        public string Name { get; set; }
    }
&lt;/pre&gt;
Service Contract - czyli funkcje wystawiane. Moje funkcje nie są ani eleganckie ani prawdziwe. Otrzymany ID powinno się przetworzyć jakoś sensownie a nie tworzyć nowy obiekt do zwrócenia, podobnie jest z tworzeniem nowej listy w metodzie pobierającej osoby. Ale ważne są nie dane a atrybuty&lt;br/&gt; 
&lt;span style="font-weight:bold;"&gt;[ServiceContract]&lt;/span&gt;  wskazuje że dana klasa będzie serwisem - potem ją powiążemy z URI i będziemy mogli korzystać.&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;[WebGet(UriTemplate ="")]&lt;/span&gt; definicja metody - jeśli nie podamy metody to wiadomo że chodzi o GET tutaj mamy listę naszych kontaktów, UriTemplate steruje URI, jeśli chcemy konkretny kontakt to przekazujemy jego ID, które będzie parametrem wejściowym do metody - używamy UriTemplate = "{id}"&lt;br/&gt;
Niestety parametry są zawsze stringiem i trzeba zadbać o walidację&lt;br/&gt;
Wszystkie konstrukcje są spójne z MVC.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 [ServiceContract]
    public class ContactsApi
    {
        [WebGet(UriTemplate = "")]
        public IQueryable&lt;Contact&gt; Get()
        {
            var contacts = new List&lt;Contact&gt;()
                {
                    new Contact {ContactId = 1, Name = "Glenn Block"},
                    new Contact {ContactId = 2, Name = "Howard Dierking"}
                };
            return contacts.AsQueryable();
        }

        [WebGet(UriTemplate = "{id}")]
        public Contact GetContact(string id)
        {
            return new Contact { ContactId = 100, Name = "JL" };
        }
    }
&lt;/pre&gt;
Pozostaje Global.asax i rejestracja URI. Wcinamy się przed standardowym &lt;span style="font-weight:bold;"&gt;routes.MapRoute(...)&lt;/span&gt;, ponieważ w innym wypadku wszystkożerna konstrukcja przechwytywała by nasze URI rejestrowane za pomocą &lt;span style="font-weight:bold;"&gt;MapServiceRoute &lt;/span&gt;(extension method z Microsoft.ApplicationServer.Http.Activation)
&lt;pre name="code" class="brush:c-sharp;"&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.ApplicationServer.Http.Activation;
using Microsoft.ApplicationServer.Http.Description;
using WcfWebApi.APIs;

namespace WcfWebApi
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
          
           
            routes.MapServiceRoute&lt;ContactsApi&gt;("api/contacts"); //!!!!
           
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }
    }
}
&lt;/pre&gt;
To by było na tyle. Teraz możemy zobaczyć efekt naszej pracy (ograniczymy się na razie do najprostszej postaci czyli XMLa w przeglądarce):
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-WGOgtsmRdDk/Ti2PWrkXsMI/AAAAAAAAAOo/VVC9THFpkP8/s1600/WebApi4_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://1.bp.blogspot.com/-WGOgtsmRdDk/Ti2PWrkXsMI/AAAAAAAAAOo/VVC9THFpkP8/s400/WebApi4_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633316328725524674" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-Guehsm9wVrU/Ti2PrQTN_bI/AAAAAAAAAOw/QXU9C41gOkY/s1600/WebApi4_3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 218px;" src="http://2.bp.blogspot.com/-Guehsm9wVrU/Ti2PrQTN_bI/AAAAAAAAAOw/QXU9C41gOkY/s400/WebApi4_3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5633316682183081394" /&gt;&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-6064556747359805498?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/6064556747359805498/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=6064556747359805498&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6064556747359805498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6064556747359805498'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/08/4-wcf-web-api-simple-get.html' title='4. WCF Web Api - simple GET'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-6_8zQOJKxE0/Ti2J-QDmoSI/AAAAAAAAAOg/fIIGs3_-tvk/s72-c/WebApi4_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3384984522088352272</id><published>2011-08-01T00:01:00.002+02:00</published><updated>2011-08-01T00:01:01.750+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Api'/><title type='text'>3. WCF Web Api - szybki start</title><content type='html'>Poprzednio było trochę teorii i linków do rozpoczęcia:
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/1-rest-small-introduction.html"&gt;1. REST - small introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://jlfedra.blogspot.com/2011/07/2-wcf-web-api-linkownia.html"&gt;2. WCF Web Api - linkownia&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
Tym razem jak zacząć.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Najprościej zacząć tworząc nowy projekt Asp MVC 3
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-FP2QRi0DqhQ/Tint9htbFUI/AAAAAAAAAOA/iwR_3nijc5M/s1600/webapi1_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 239px;" src="http://1.bp.blogspot.com/-FP2QRi0DqhQ/Tint9htbFUI/AAAAAAAAAOA/iwR_3nijc5M/s400/webapi1_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5632294450280207682" /&gt;&lt;/a&gt;
Warto jeszcze ustawić stały port jeśli korzystamy z Visual Studio Development Server.&lt;br/&gt;
Potrzeba nam jeszcze referencji, którą można dodać ręcznie, albo korzystając z menagera NuGet poszukujemy &lt;span style="font-weight:bold;"&gt;WebApi &lt;/span&gt;&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-dZ0qdL-C9-8/Tin0ac2-DsI/AAAAAAAAAOI/B9LBYppKwzM/s1600/webapi1_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 230px;" src="http://3.bp.blogspot.com/-dZ0qdL-C9-8/Tin0ac2-DsI/AAAAAAAAAOI/B9LBYppKwzM/s400/webapi1_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5632301544264044226" /&gt;&lt;/a&gt;
Mamy do dyspozycji - na chwilę obecną, ponieważ sytuacja jest dynamiczna - Core, All oraz CrudHttpSample. &lt;br/&gt;
All zawiera:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-zyuB57osXcw/Tin2CeqaVdI/AAAAAAAAAOQ/DgMPYxGuhA8/s1600/webapi1_23.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/-zyuB57osXcw/Tin2CeqaVdI/AAAAAAAAAOQ/DgMPYxGuhA8/s400/webapi1_23.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5632303331454637522" /&gt;&lt;/a&gt;
Core:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-rCfNVH_vfX4/Tin2X3XtdrI/AAAAAAAAAOY/QemyckVv55A/s1600/webapi1_4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/-rCfNVH_vfX4/Tin2X3XtdrI/AAAAAAAAAOY/QemyckVv55A/s400/webapi1_4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5632303698864338610" /&gt;&lt;/a&gt;
Ogólnie rzecz biorąc po dodaniu referencji to już jest koniec przygotowań. Możemy zacząć wystawiać nasze zasoby.&lt;br/&gt;
Jeszcze słówko jeśli chodzi o to - gdzie to wepchnąć, ja obrałam taką strukturę jak na przykładzie prezentowanym na codeplexie, ale jest to w pełni dowolna sprawa. Dla mnie to:&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Resources &lt;/span&gt;- dla obiektów&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;APIs &lt;/span&gt;- dla serwis kontraktów.


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3384984522088352272?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3384984522088352272/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3384984522088352272&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3384984522088352272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3384984522088352272'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/08/3-wcf-web-api-szybki-start.html' title='3. WCF Web Api - szybki start'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-FP2QRi0DqhQ/Tint9htbFUI/AAAAAAAAAOA/iwR_3nijc5M/s72-c/webapi1_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-6578298872305178024</id><published>2011-07-27T23:59:00.002+02:00</published><updated>2011-07-27T23:59:00.070+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Api'/><title type='text'>2. WCF Web API - linkownia</title><content type='html'>&lt;b&gt;WCF Web API - linki gdzie warto zajrzeć w poszukiwaniu wiedzy o serwisach REST&lt;/b&gt;&lt;br/&gt;

Poprzednio :
&lt;a href="http://jlfedra.blogspot.com/2011/07/1-rest-small-introduction.html"&gt;1. REST - small introduction&lt;/a&gt; &lt;br/&gt;
Teraz małe zapoznanie z WCF REST Starter Kit i WCF Web API.&lt;br/&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Pierwszym projektem REST był &lt;a href="http://aspnet.codeplex.com/wikipage?title=WCF%20REST&amp;referringTitle=Home"&gt;WCF REST Starter Kit&lt;/a&gt; i wbrew pozorom warto się nad nim chwilę pochylić. Ponieważ StarterKit istniał przez dłuższy czas zdążyła wytworzyć się mała baza wiedzy. Oczywiście zmieniły się nazwy klas, metod i inne szczegóły, ale ważne są pewne zasady, ogólny zarys a to można poznać np w serii &lt;a href="http://channel9.msdn.com/Tags/rest+starter+kit?page=2"&gt;ScreenCastów stworzonych przez Pluralsight&lt;/a&gt;
&lt;!--
zestaw linkow 
http://msdn.microsoft.com/en-us/library/ee391967.aspx
http://weblogs.asp.net/cibrax/archive/tags/REST+Starter+Kit/default.aspx

--&gt;
&lt;br/&gt;
&lt;br/&gt;
Obecnie obowiązującą implementacją Rest jest &lt;a href="http://wcf.codeplex.com/wikipage?title=WCF HTTP"&gt;WCF Web Api Preview 4&lt;/a&gt;
Na stronie domowej projektu znajdziemy sporo przydatnych informacji jak przewodnik jak zacząć i linki do najlepszych blogów.&lt;br/&gt;
Jeśli już o blogach mowa to oto link to najbardziej rozbudowanej serii postów:
&lt;a href="http://blog.alexonasp.net/post/2011/04/15/Microsoft-Web-API-e28093-the-REST-is-done-by-WCF-(Part-1).aspx"&gt; Alex on ASP.NET &lt;/a&gt;
Warto też spojrzeć na posty Steve'a Michelotti &lt;a href="http://geekswithblogs.net/michelotti/archive/2011/04/21/wcf-web-api-is-pure-simplicity-with-nuget.aspx"&gt;WCF Web API is Pure Simplicity with NuGet 
&lt;/a&gt; oraz &lt;a href="http://geekswithblogs.net/michelotti/archive/2011/07/14/leverage-t4scaffolding-for-wcf-web-api.aspx"&gt;Leverage T4Scaffolding for WCF Web API &lt;/a&gt;

&lt;br/&gt;
Oczywiście w linkowni nie powinno zabraknąć:
&lt;ul&gt;
&lt;li&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://live.visitmix.com/MIX11/Sessions/Speaker/Glenn-Block"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 123px; height: 147px;" src="http://2.bp.blogspot.com/-2SWdw83JUG0/TinG3MU-V5I/AAAAAAAAAN4/hcVigyDoa1Y/s400/image.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5632251460507817874" /&gt;WCF Web APis: "There's a URI for That"
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.talkingshopdownunder.com/2011/01/episode-41-glenn-block-wcf-and-http.html"&gt;Talking Shop Down Under - Episode 41 - Glenn Block, WCF and HTTP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://codebetter.com/glennblock/2011/03/07/adding-vcard-support-and-bookmarked-uris-for-specific-representations-with-wcf-web-apis/"&gt;Glenn Block - reprezentacja vcard&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
Coraz to więcej informacji pojawia się tu i ówdzie, jednak nie ma ich aż tak dużo, zapewne kolejny wysyp będzie miał miejsce jesienią. Prawdopodobnie na jesień pojawi się też kolejna wersja Web Api (pojawiły się pogłoski o końcu czerwca, jednak nie ziściły się).
&lt;br/&gt;
&lt;br/&gt;
Przed dalszą częścią zachęcam do obejrzenia sesji o serwisie REST dla standardowego WCFa: 
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://ndc2011.macsimum.no/SAL6/Fredag/1500-1600.wmv
"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 88px;" src="http://2.bp.blogspot.com/-oczGLP63bhw/Ti3nNpPgnyI/AAAAAAAAAO4/6G-m4eHVeJw/s400/logoNDC2011-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5633412930505580322" /&gt;To Rest Or Not To Rest by Miguel Castro&lt;/a&gt;
oraz sesji o Rest prowadzonej przez współautora książki &lt;a href="http://www.amazon.com/REST-in-Practice-ebook/dp/B0046RERXY"&gt;Rest in practice&lt;/a&gt; Iana Robinsona

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://ndc2011.macsimum.no/SAL2/Fredag/1020-1120.wmv"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:left;cursor:pointer; cursor:hand;width: 400px; height: 88px;" src="http://2.bp.blogspot.com/-oczGLP63bhw/Ti3nNpPgnyI/AAAAAAAAAO4/6G-m4eHVeJw/s400/logoNDC2011-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5633412930505580322" /&gt;Getting Things Done with REST
 by Ian Robinson&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-6578298872305178024?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/6578298872305178024/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=6578298872305178024&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6578298872305178024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6578298872305178024'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/2-wcf-web-api-linkownia.html' title='2. WCF Web API - linkownia'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-2SWdw83JUG0/TinG3MU-V5I/AAAAAAAAAN4/hcVigyDoa1Y/s72-c/image.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-6286941050593019612</id><published>2011-07-26T22:59:00.001+02:00</published><updated>2011-07-26T23:11:43.333+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Api'/><title type='text'>1. REST - small introduction</title><content type='html'>&lt;b&gt;Co to jest REST?  &lt;/b&gt;
&lt;br/&gt;
Na DevDeys 2010 Aaron Skonnard prowadził prezentację 
&lt;a href="http://channel9.msdn.com/Blogs/matthijs/Why-REST-by-Aaron-Skonnard"&gt;Why we need some REST?&lt;/a&gt;. To będzie małe streszczenie z moimi przemyśleniami i zapewne ogromnym chaosem myśli (za który przepraszam).
&lt;span class="fullpost"&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;span style="color:green; font-style:italic;"&gt;/*
Ten post powstawał baardzoo długo i mam nadzieje że przerodzi się w kompletny cykl, a być może i więcej. Wszystkie spostrzeżenia i naprostowania mnie na właściwą drogę mile widziane ;) 
*/&lt;br/&gt;&lt;br/&gt;
&lt;/span&gt;
Zanim przejdziemy do głównego tematu - REST spójrzmy na znacznie bardziej obecnie znany standard &lt;span style="font-weight:bold;"&gt;SOAP&lt;/span&gt; (Simple Object Access Protocol):&lt;br/&gt;
Dobre strony SOAP: standaryzacja, service metadata, szeroki wachlarz narzędzi.
SOAP operuje na wiadomościach XML wysyłanych do zdefiniowanego punktu końcowego (endpoint). Serwis odbierający wiadomość decyduje się co dalej zrobić na podstawie akcji zawartej w nagłówku - według standardu WS-Addressing. Wiadomości XML wysyłane przez HTTP zawsze będą  używać metody POST, właściwie SOAP nie potrzebuje do szczęścia nic innego. WSDL opisuje endpointy zawiera wszystkie operacje które może wysłać i odebrać. Ponieważ zawsze używana jest metoda POST nie możliwe jest korzystanie z mechanizmu Cashing i każda wiadomość podróżuje zawsze od web serwera aż do endpoint.&lt;br/&gt;
Yachoo, Amazon i Google (Google na początku było zbudowane na SOAP) nie używają SOAP, głównie we względu na duże zróżnicowanie odbiorców.&lt;br/&gt;
&lt;br/&gt;
Więc co to jest &lt;span style="font-weight:bold;"&gt;REST&lt;/span&gt;? &lt;br/&gt;
Representational State Transfer  - termin przedstawiony w roku 2000 przez jednego z głównych twórców protokołu HTTP Roya Fieldinga w jego pracy doktoranckiej. REST określa model, zasady umożliwiające budowanie rozwiązań (network architecture) które pozwalają na bardzo dużą skalowalność sieci (i własnych rozwiązań). Model ten to zasób (obiekt/Resource) + reprezentujący go URI. Lub z drugiej strony - każdy URI wskazuje na jakiś obiekt.
&lt;br/&gt; 
Ponieważ każdy zasób reprezentowany jest przez oddzielny URL nie ma takiej konieczności aby wszystkie zasoby znajdowały się w tym samym miejscu. Każdy zasób (lub dowolny podzbiór) może znajdować się na innym hoście. Rest oprócz zasobów reprezentowanych przez Uri to również kwestia reprezentacji - dany zasób może być reprezentowany jako wynik typu XML, Json, Image i inne.

&lt;br/&gt;
Można więc w wielkim skrócie powiedzieć:&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;REST = zasób + reprezentacja&lt;/span&gt;

&lt;br/&gt;
Do tej pory Microsoft wydaje się że mocno stawiał na architekturę SOAP pomijając z lekka REST. SOAP jest zorientowany na obiekty i może transportować dane przez wiele protokołów. Dodatkowo istnieje cała masa mechanizmów rozszerzających funkcjonalność SOAP a wszystkie z przedrostkami WS, które nie są dostępne dla HTTP. REST działa bardziej jak sam HTTP i wykorzystuje jego całą moc.
&lt;br/&gt;
SOAP i REST to dwie różne drogi.&lt;br/&gt;

&lt;br/&gt;
Microsoft opanował się dopiero przy .NET 3.5 i udostępnił pierwsze implementacje RESTa abyśmy my programiści mogli iść dowolnie wybraną ścieżką. W końcu nie ma idealnego rozwiązania/technologii/architektury do wszystkiego (jak coś jest do wszystkiego to jest...). 
WCF przedstawił WebRequest w Rest Toolkit.&lt;br/&gt;
Na pewno SOAP będzie wykorzystywany w wielu aplikacjach, jednak jeśli potrzebny jest wam serwis udostępniający dane poprzez internet, który może się rozrastać  i który będzie miał wielu odbiorców - to zapewne REST będzie lepszy. (w kierunku chmur to chyba jedyna droga).&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style="font-weight:bold;"&gt; REST &lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style="font-weight:bold;"&gt;SOAP&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
Bezstanowy&lt;/td&gt;
&lt;td&gt;
Może być stanowy
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
Nie wspiera transakcji&lt;/td&gt;
&lt;td&gt;
Wspiera transakcje
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
"Transfer specific" czyli zawsze używamy HTTP.&lt;br/&gt;
Znaczy to że zawsze przesyłamy dane tekstowe - więc wysyłamy je powoli, ale możemy dostać się np za Firewall &lt;/td&gt;
&lt;td&gt;
Może używać różnych standardów transportu. np wewnątrz sieci może posługiwać się TCP, jeśli ograniczymy się do jednej maszyny może korzystać z IPC. Dzięki temu może być bardzo szybki.
&lt;/td&gt;
&lt;tr/&gt;

&lt;tr&gt;
&lt;td&gt;
Bardzo interoperacyjny (interoperable)
&lt;/td&gt;
&lt;td&gt;
Interoperacyjny ale tylko w zakresie bindingu (transportu), odbiorca musi rozumieć dany standard wysyłanych danych co nie zawsze jest łatwe (np w iPhonach)
&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;td&gt;
Zawsze posługuje się interfacem GET POST PUT DELETE - czyli CRUD w najczystszej postaci
&lt;/td&gt;
&lt;td&gt;
Nie przejmuje się HTTP, zawsze używa POST oraz swoich standardów (WSDL, WS*)
&lt;/td&gt;
&lt;tr/&gt;



&lt;tr&gt;
&lt;td&gt;
słabo typowany&lt;/td&gt;
&lt;td&gt;
silnie typowany w oparciu o kontrakt &lt;/td&gt;
&lt;tr/&gt;



&lt;tr&gt;
&lt;td&gt;
nastawienie na zasoby
&lt;/td&gt;
&lt;td&gt;
nastawienie na operacje
&lt;/td&gt;
&lt;tr/&gt;


&lt;tr&gt;
&lt;td&gt;
Bardzo czytelne wiadomości, niewielki narzut do wielkości wiadomości. Każdy klient HTTP powinien sobie poradzić z odczytaniem wiadomości
&lt;/td&gt;
&lt;td&gt;
Skomplikowane i zawsze obudowane wiadomości. Wymaga wiedzy i narzędzi do otworzenia/odebrania wiadomości.
&lt;/td&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;td&gt;
Zasoby/obiekty identyfikowane są przez URL (sieć to graf połączonych zasobów)&lt;br/&gt;
jeśli tylko restrykcje biznesowe na to pozwalają zawsze można powrócić do bieżącego URL
&lt;!--

&lt;tr&gt;
&lt;td&gt;
Wykorzystuje HTTP, opiera się na warstwie transportu
&lt;/td&gt;
&lt;td&gt;
Nie przywiązuje wagi do warstwy transportu - zrobi wszystko po swojemu - zawsze request uderza do zdefiniowanego punktu końcowego gdzie dopiero może zostać przefiltrowany, warstwa transportu nie ma prawa zaingerować
&lt;/td&gt;
&lt;tr/&gt;

REST 
– the web is a graph of linked Resources
- Resources are identified by URI’s
- Resources support a uniform interface (get, post, put delete – not have to be all at once)
- Applications follow links for late binding 
--&gt;
&lt;/td&gt;
&lt;td&gt;
Operacje wykonywane są w sekwencji i nie zawsze da się powrócić do każdego/dowolnego punktu
&lt;/td&gt;
&lt;tr/&gt;


&lt;tr&gt;
&lt;td&gt;
ograniczone możliwości zabezpieczania (security)&lt;/td&gt;
&lt;td&gt;
wspiera wiele modeli zabezpieczeń
&lt;/td&gt;
&lt;tr/&gt;

&lt;/table&gt;

&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Dlaczego REST&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt; Większość ludzi nie potrzebuje kluczowych funkcji SOAP czyli neutralności warstwy transportu oraz zaawansowanych protokołów WS &lt;/li&gt;
&lt;li&gt; REST jest prosty , ujednolicony (uniform) i composable -&gt;&lt;br/&gt;
&lt;span style="color:gray;"&gt;nie umiem znaleźć ładnego słowa kojarzą mi się tylko klocki Lego - każdy do każdego pasuje, każdy można wymienić na inny a budować można duże konstrukcje, i każdy wie jak budować z klocków Lego - dokładnie tego porównania używają również prelegenci opowiadający o REST. Interface jest jeden i jest prosty i wszyscy go znają – co nie ogranicza nas w tworzeniu skomplikowanych rozwiązań.&lt;br/&gt;
&lt;span style="font-style:italic;"&gt;A przynajmniej taka jest teoria bo jak pierwszy raz siada się do RESTa – do konsumpcji - człowiek jest zagubiony nie ma web referencji, nie ma klasy proxy – I co tu zrobić.Interakcja z HTTP wydaje się być tabu – tego nie powinno się robić - takie wrażenie zostaje po latach używania mydła.Samo to nie przychodzi do głowy &lt;!-- – jak skonsumowac rest (HTTPClient??)--&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;REST zapewnia szerszy zasięg (choćby iPhony Androidy...) &lt;!-- broader reach --&gt;
&lt;/li&gt;
&lt;li&gt; REST działa tak jak internet i korzysta z wbudowanych mechanizmów takich jak caching, bookmarking, linki, SSL, dostępność przez przeglądarki internetowe.&lt;/li&gt;
&lt;/ul&gt;
&lt;!--
&lt;br/&gt;
WCF DataServices – to jest obudowanie WCFa i RESTa – ale odnosi się tylko do bazy danych, tylko do modelu.

SOAP is PC based!!

--&gt;

&lt;span style="font-weight:bold;"&gt;Czemu SOAP?&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;
Przywykliśmy 
&lt;/li&gt;
&lt;li&gt; zabezpieczenia(wbudowane)&lt;/li&gt;
&lt;li&gt;tranzakcyjność&lt;/li&gt;
&lt;li&gt;
W pewnych zastosowaniach jest szybszy&lt;/li&gt;
&lt;li&gt;
zapewne lepiej sprawdzi się w bardzo dużych rozwiązaniach za firewallem
&lt;/li&gt;
&lt;/ul&gt;

&lt;br/&gt;
&lt;br/&gt;

WCF praktycznie od samego początku 
&lt;span style="font-weight:bold;"&gt;REST StarterKit &lt;/span&gt;podobnież miał być częścią kolejnego frameworka, jednak na konferencji MIX11 ogłoszono preview &lt;span style="font-weight:bold;"&gt;WCF Web Api&lt;/span&gt;, które jest następcą StarterKita, ale o tym w kolejnych postach.
&lt;br/&gt;
&lt;br/&gt;
•Na podstawie:
&lt;a href="http://channel9.msdn.com/Blogs/matthijs/Why-REST-by-Aaron-Skonnard"&gt;
Why REST? by Aaron Skonnard   15.04.2010 &lt;/a&gt;


&lt;/span&gt;

&lt;!--
http://www.developerfusion.com/article/7991/rest-and-net-35-part-1-why-rest-based-services/

--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-6286941050593019612?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/6286941050593019612/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=6286941050593019612&amp;isPopup=true' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6286941050593019612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/6286941050593019612'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/1-rest-small-introduction.html' title='1. REST - small introduction'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-1264380705309153755</id><published>2011-07-13T23:20:00.000+02:00</published><updated>2011-07-13T23:20:01.474+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Narzędzia'/><title type='text'>DPack Numbered Bookmarks</title><content type='html'>&lt;b&gt;Numerowane zakładki&lt;/b&gt;
&lt;br/&gt;
Chyba każdy kto kiedyś programował w Delphi był potem rozczarowany standardowymi bookmarkami w VS. Jak działają bookmarki w VS? &lt;br/&gt;
Skrótem &lt;span style="font-weight:bold;"&gt;Ctrl+K; Ctrl+K&lt;/span&gt; ustawiamy bookmarka. Możemy ich mieć dowolną ilość.
&lt;span class="fullpost"&gt;
Bookmarki możemy sobie podejrzeć w okienku dla nich przeznaczonym:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-cIK_DrKy9bk/Th2GUaYe4sI/AAAAAAAAANw/n2otmdJkBmo/s1600/NumberedBookmarks2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 81px;" src="http://3.bp.blogspot.com/-cIK_DrKy9bk/Th2GUaYe4sI/AAAAAAAAANw/n2otmdJkBmo/s400/NumberedBookmarks2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5628802794520502978" /&gt;&lt;/a&gt;
Możemy sobie zmieniać ich nazwę, ale nie kolejność. I to jest właśnie ten element który jest niekoniecznie fajny. &lt;br/&gt;
Poruszanie się po bookmarkach&lt;span style="font-weight:bold;"&gt; Ctrl+K;Ctrl+N&lt;/span&gt; (następna) oraz &lt;span style="font-weight:bold;"&gt;Ctrl+K;Ctrl+P&lt;/span&gt; (poprzednia) przechodzi do kolejnych bookmarków - zgodnie z ich kolejnością dodawania. W tym można się łatwo zaplątać, zwłaszcza jak jakąś usuniemy, zamkniemy projekt i spędzimy wieczór bez VS czy cokolwiek.&lt;br/&gt;
&lt;br/&gt;
Jeśli potrzeba nam ścieżki "skąd ja się tu kurcze wziąłem" dużo lepiej zadziała nawigacja wstecz czyli&lt;span style="font-weight:bold;"&gt; Ctrl+-&lt;/span&gt; (wstecz) &lt;span style="font-weight:bold;"&gt;Ctrl+Shift+-&lt;/span&gt; (w przód)&lt;br/&gt;
&lt;br/&gt;
Jednak czasem jak się wpada w nowy projekt miło jest wiedzieć więcej i szybciej (niż np przezywanie bookmarków). 
W VS2010 można użyć &lt;a href="http://visualstudiogallery.msdn.microsoft.com/50b12550-622c-4790-a101-4715b7d9ce88"&gt;Numbered Bookmarks by TheManojKumar&lt;/a&gt;, jednak ta wtyczka ma ograniczenie numerowania bookmarków w zakresie jednego pliku.
&lt;br/&gt;
No więc TaDa: 
&lt;a href="http://www.usysware.com/dpack/"&gt;DPack&lt;/a&gt;&lt;br/&gt;
DPack, który jest dostępny dla VS2010 oraz VS2008, rozszerza VS o numerowane bookmarki
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/--JSONlWooTk/Th1uJuMmE_I/AAAAAAAAANo/Uz6jc6sQ8io/s1600/NumberedBookmarks1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 62px;" src="http://4.bp.blogspot.com/--JSONlWooTk/Th1uJuMmE_I/AAAAAAAAANo/Uz6jc6sQ8io/s400/NumberedBookmarks1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5628776222581724146" /&gt;&lt;/a&gt;
Po użyciu odpowiedniego skrótu klawiaturowego zostaje dodany bookmark wyglądający jak standardowy VS, z tą różnicą że ma cyferkę. Bookmarki można ustawiać w zasięgu pliku, ale również globalnie dla projektu. Możemy oczywiście mieć 10 bookmarków naraz i zapisują się one w naszych ustawieniach (suo) więc dnia następnego nadal będą tam gdzie je zostawiliśmy (jeśli tylko pamiętamy po co...)
&lt;br/&gt;
Skróty dla DPack bookmark - globalne
Ustaw:&lt;span style="font-weight:bold;"&gt; Shift+Ctrl+Alt+0..9 &lt;/span&gt;
Idź:   &lt;span style="font-weight:bold;"&gt;Ctrl+Alt+0..9&lt;/span&gt;


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-1264380705309153755?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/1264380705309153755/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=1264380705309153755&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1264380705309153755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1264380705309153755'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/dpack-numbered-bookmarks.html' title='DPack Numbered Bookmarks'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-cIK_DrKy9bk/Th2GUaYe4sI/AAAAAAAAANw/n2otmdJkBmo/s72-c/NumberedBookmarks2.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-309007027805213360</id><published>2011-07-04T23:00:00.000+02:00</published><updated>2011-07-04T23:00:00.900+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Event in Reflector</title><content type='html'>Ostatnio rozgryzałam Reflectorem BindingListe natrafiłam na taki kod:
&lt;span class="fullpost"&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
[NonSerialized]
private ListChangedEventHandler onListChanged;
// Events
public event ListChangedEventHandler ListChanged;

protected virtual void OnListChanged(ListChangedEventArgs e)
{
    if (this.onListChanged != null)
    {
        this.onListChanged(this, e);
    }
}

private void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
[...]
        ListChangedEventArgs args = new ListChangedEventArgs(ListChangedType.ItemChanged, lastChangeIndex, propDesc);
        this.OnListChanged(args);
    }
}
&lt;/pre&gt;
Co gorsza oglądałam ten sam kod w Telerikowym JustDecompile, który z kolei nie oznacza &lt;span style="color:blue;"&gt;[NonSerialized]&lt;/span&gt; i jakoś nie potrafiłam tego poskładać. &lt;br/&gt;
Ponieważ ten event był dla mnie kluczowy postanowiłam poszukać głębiej.
&lt;br/&gt;
Znalazłam link do &lt;a href="http://referencesource.microsoft.com/netframework.aspx"&gt;kodu źródłowego .NET 4&lt;/a&gt; (kod jest udostępniany w jednym około 180MB pliku i można go wykorzystać do debuggowania bez uciążliwego ściągania źródeł w trakcie debuggowania. &lt;a href="http://blogs.microsoft.co.il/blogs/arik/archive/2010/07/12/step-into-net-framework-4-0-source-code.aspx"&gt;"Step Into .NET Framework 4.0 Source Code"&lt;/a&gt;.
&lt;br/&gt;
Okazuje się że interesujący mnie event jest zapisany tak:
&lt;pre name="code" class="brush:c-sharp;"&gt;
[NonSerialized]
private ListChangedEventHandler onListChanged;

public event ListChangedEventHandler ListChanged
{
     add
     {
         onListChanged += value;
     }
     remove
     {
         onListChanged -= value;
     }
}
&lt;/pre&gt;
Niby dość oczywiste a jednak ;)&lt;br/&gt;
Oprócz samego zapisu eventa w sposób podobny do Property istotny wniosek jest taki że JustDecompile jest jeszcze młodym narzędziem.


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-309007027805213360?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/309007027805213360/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=309007027805213360&amp;isPopup=true' title='Komentarze (3)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/309007027805213360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/309007027805213360'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/event-in-reflector.html' title='Event in Reflector'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-4685020334108939810</id><published>2011-07-01T20:01:00.000+02:00</published><updated>2011-07-01T20:01:00.288+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Snippet Designer</title><content type='html'>&lt;b&gt;&lt;a href="http://snippetdesigner.codeplex.com/"&gt;Snippet Designer&lt;/a&gt; &lt;/b&gt;
&lt;br/&gt;
Często piszę swoje snippety, choćby zaczynając od Propercji z prywatnym polem ponieważ w VS2008 w standardzie zapomniano o tym snippecie.&lt;br/&gt;
Pisanie snippetów sprowadza się do napisania xmla w którym pewne pola będą dostępne do zmiany, zadeklarowanie ich jako &lt;span style="color:blue;"&gt;Literal &lt;/span&gt; i używanie w snippecie jako &lt;span style="color:blue;"&gt;$literal$&lt;/span&gt;.&lt;br/&gt;
&lt;span class="fullpost"&gt;
Oto snippet dla c# dla propercji.
&lt;pre class='brush: xml'&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;CodeSnippets  xmlns=&amp;quot;http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet&amp;quot;&amp;gt;
  &amp;lt;CodeSnippet Format=&amp;quot;1.0.0&amp;quot;&amp;gt;
  &amp;lt;Header&amp;gt;
    &amp;lt;Title&amp;gt;prop&amp;lt;/Title&amp;gt;
    &amp;lt;Shortcut&amp;gt;prop&amp;lt;/Shortcut&amp;gt;
    &amp;lt;Description&amp;gt;Code snippet for an automatically implemented property&amp;lt;/Description&amp;gt;
    &amp;lt;Author&amp;gt;Microsoft Corporation&amp;lt;/Author&amp;gt;
    &amp;lt;SnippetTypes&amp;gt;
    &amp;lt;SnippetType&amp;gt;Expansion&amp;lt;/SnippetType&amp;gt;
    &amp;lt;/SnippetTypes&amp;gt;
  &amp;lt;/Header&amp;gt;
  &amp;lt;Snippet&amp;gt;
    &amp;lt;Declarations&amp;gt;
    &amp;lt;Literal&amp;gt;
      &amp;lt;ID&amp;gt;type&amp;lt;/ID&amp;gt;
      &amp;lt;ToolTip&amp;gt;Property type&amp;lt;/ToolTip&amp;gt;
      &amp;lt;Default&amp;gt;int&amp;lt;/Default&amp;gt;
    &amp;lt;/Literal&amp;gt;
    &amp;lt;Literal&amp;gt;
      &amp;lt;ID&amp;gt;property&amp;lt;/ID&amp;gt;
      &amp;lt;ToolTip&amp;gt;Property name&amp;lt;/ToolTip&amp;gt;
      &amp;lt;Default&amp;gt;MyProperty&amp;lt;/Default&amp;gt;
    &amp;lt;/Literal&amp;gt;
    &amp;lt;/Declarations&amp;gt;
    &amp;lt;Code Language=&amp;quot;csharp&amp;quot;&amp;gt;
    &amp;lt;![CDATA[public $type$ $property$ { get; set; }$end$]]&amp;gt;
    &amp;lt;/Code&amp;gt;
  &amp;lt;/Snippet&amp;gt;
  &amp;lt;/CodeSnippet&amp;gt;
&amp;lt;/CodeSnippets&amp;gt;

&lt;/pre&gt;

Snippety dla C# znajdują się w: [Program Files]\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\
&lt;br/&gt;
&lt;br/&gt;
W cyklu &lt;a href="http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-Toolbox-Creating-and-Using-Code-Snippets"&gt;Visual Studio Toolbox&lt;/a&gt; zaprezentowano niedawno Snippet Designer, który uprzyjemnia pracę przy tworzeniu snippetów.&lt;br/&gt;
Co bardzo miłe Snippet Designer jest również w wersji dla VS2008.&lt;br/&gt;
&lt;br/&gt;
Jak teraz tworzy się snipett?&lt;br/&gt;
Z menu kontekstowego wybieramy "Export as snippet" - jeśli mamy zaznaczony jakiś fragment kodu zostanie on przeniesiony do edytora snippetów, jeśli nie w edytorze możemy spokojnie wpisywać swój kod.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-Ksx5jVnj9sA/Tg3FC6r4LzI/AAAAAAAAANI/JrtwmX8LqDU/s1600/snippet1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 161px; height: 400px;" src="http://3.bp.blogspot.com/-Ksx5jVnj9sA/Tg3FC6r4LzI/AAAAAAAAANI/JrtwmX8LqDU/s400/snippet1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5624368163559321394" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-DjwuEtQMKKc/Tg3FIigW4wI/AAAAAAAAANQ/jNHyV92kL2s/s1600/snippet2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://4.bp.blogspot.com/-DjwuEtQMKKc/Tg3FIigW4wI/AAAAAAAAANQ/jNHyV92kL2s/s400/snippet2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5624368260147766018" /&gt;&lt;/a&gt;
A potem wybieramy pola które chcemy aby było wprowadzane przy używaniu snippeta i robimy "Make replacement". Wszystkie użycia zostają zastąpione $newliteral$, dla którego możemy ustawić wartość domyślną, opis, nazwę i co tam jeszcze się nam spodoba.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-x604UdeOjRk/Tg3YNCLBOyI/AAAAAAAAANg/4YIq4SfQYQI/s1600/snippet3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://1.bp.blogspot.com/-x604UdeOjRk/Tg3YNCLBOyI/AAAAAAAAANg/4YIq4SfQYQI/s400/snippet3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5624389228088605474" /&gt;&lt;/a&gt;
Praca jest wizualna i zacznie przyjemniejsza :).
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-4685020334108939810?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/4685020334108939810/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=4685020334108939810&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4685020334108939810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4685020334108939810'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/snippet-designer.html' title='Snippet Designer'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Ksx5jVnj9sA/Tg3FC6r4LzI/AAAAAAAAANI/JrtwmX8LqDU/s72-c/snippet1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2500007058363732177</id><published>2011-07-01T20:00:00.004+02:00</published><updated>2011-07-01T20:24:22.141+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>Powrót zielonego .Net Ninja</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.telerik.com/products/ninja-in-the-maze.aspx"&gt;&lt;img style="float:left; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 223px; height: 389px;" src="http://3.bp.blogspot.com/-gjTNciiYFfY/Tg2gRjllbRI/AAAAAAAAAL4/URlEEdLck0I/s400/.netNinja.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5624327733126720786" /&gt;
&lt;/a&gt;
&lt;b&gt;Telerik Q2 2011 - nowa wersja kontrolek i narzędzi Telerik nadchodzi.&lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Wraz z zapowiedzą Q2 powrócił zielony ninja promujący nową wersje produktów firmy Telerik. Ninja tym razem biega po labiryncie rozwalając robaki (te czerwone są irytujące bo go gonią) i zarabiając telerikowe dolarki, które później możemy wymienić na produkty firmy.&lt;br/&gt;
Ninja pozostanie z nami aż do tygodnia webinariowego i oficjalnego pojawienia się Q2.
&lt;br/&gt;
Tydzień webinariów jest doprawdy upakowany w spotkania. Warto uczestniczyć w spotkaniach online aby poznać możliwości produktów. Czasem przekazywane są dobre wieści jak zamiary tworzenia nowych produktów, no i oczywiście zawsze jest nikła szansa na wygranie licencji. Nikła? czasem Telerik rozdaje licencje wszystkim uczestnikom - zazwyczaj na premierach produktu :)
&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
Poniżej rozpiska webinariów a &lt;a href="http://www.telerik.com/support/webinars.aspx"&gt;tutaj link do rejestracji&lt;/a&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
2011-07-18&lt;br/&gt;
17:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New Q2 Overview &amp; Data Tools&lt;/span&gt;
&lt;br/&gt;
Kick-off oraz szybki przegląd co nowego. A potem bardziej szczegółowy przegląd co nowego w narzędziach OpenAccess ORM, OpenAccess Profiler.
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-7tmvuWDCOpA/Tg2hVFOnEDI/AAAAAAAAAMA/AKtGL3EAaho/s1600/1Q2%2526ORM.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://3.bp.blogspot.com/-7tmvuWDCOpA/Tg2hVFOnEDI/AAAAAAAAAMA/AKtGL3EAaho/s400/1Q2%2526ORM.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624328893208399922" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-18&lt;br/&gt;
20:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New for Windows Phone&lt;/span&gt;
&lt;br/&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-E1jD62uZ8Nk/Tg2hllv9kUI/AAAAAAAAAMI/4Q_e6YUcBjM/s1600/2WP7_smaller.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://3.bp.blogspot.com/-E1jD62uZ8Nk/Tg2hllv9kUI/AAAAAAAAAMI/4Q_e6YUcBjM/s400/2WP7_smaller.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624329176816128322" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-19&lt;br/&gt;
17:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New for Web Developers&lt;/span&gt;
&lt;br/&gt;
Oczywiście że nie zabraknie zmian w związku z HTML5 ;)
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-tAp976afqfg/Tg2iTi3d9sI/AAAAAAAAAMQ/i6k-jPueUyE/s1600/3MVC_AJAX_Combined.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://3.bp.blogspot.com/-tAp976afqfg/Tg2iTi3d9sI/AAAAAAAAAMQ/i6k-jPueUyE/s400/3MVC_AJAX_Combined.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624329966316287682" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-19&lt;br/&gt;
20:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What’s New in Telerik Test Studio&lt;/span&gt;&lt;br/&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-RvXMRzwYTgA/Tg2i2yG5tTI/AAAAAAAAAMY/ObC7YPILIaw/s1600/4Test_Studio_smaller.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://4.bp.blogspot.com/-RvXMRzwYTgA/Tg2i2yG5tTI/AAAAAAAAAMY/ObC7YPILIaw/s400/4Test_Studio_smaller.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624330571702973746" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-20&lt;br/&gt;
17:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New for XAML Developers (Silverlight/WPF)&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-JWIMuLZk9ro/Tg2jPr_Ci4I/AAAAAAAAAMg/7FU5izyb-mU/s1600/5Logo_Banner_SquareSL_WPF_Smaller.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://4.bp.blogspot.com/-JWIMuLZk9ro/Tg2jPr_Ci4I/AAAAAAAAAMg/7FU5izyb-mU/s400/5Logo_Banner_SquareSL_WPF_Smaller.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624330999556115330" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-20&lt;br/&gt;
20:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New for Desktop Developers&lt;/span&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-2Wc2V7AtbIU/Tg2jeB253YI/AAAAAAAAAMo/mbNleB8aQIQ/s1600/6Winforms.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://1.bp.blogspot.com/-2Wc2V7AtbIU/Tg2jeB253YI/AAAAAAAAAMo/mbNleB8aQIQ/s400/6Winforms.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624331245945740674" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-21&lt;br/&gt;
17:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;What's New for Productivity Tools&lt;/span&gt;
&lt;br/&gt;
JustCode, JustMock, oraz JustTrace który przestanie być betą.
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-FKj31Mr4mPY/Tg2j4zp3ZII/AAAAAAAAAMw/JsG4VveG6Zs/s1600/7Justs.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://2.bp.blogspot.com/-FKj31Mr4mPY/Tg2j4zp3ZII/AAAAAAAAAMw/JsG4VveG6Zs/s400/7Justs.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624331705989424258" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-21&lt;br/&gt;
20:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;Introduction to Sitefinity eCommerce&lt;/span&gt;&lt;br/&gt;
Nowy produkt - warto sprawdzić co Telerik proponuje :)
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-thtRh1lYge4/Tg2kR9SSmOI/AAAAAAAAAM4/MqfPNL2EJ-k/s1600/8Sitefinity_smaller.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://1.bp.blogspot.com/-thtRh1lYge4/Tg2kR9SSmOI/AAAAAAAAAM4/MqfPNL2EJ-k/s400/8Sitefinity_smaller.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624332138071628002" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
2011-07-22&lt;br/&gt;
17:00
&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-weight:bold;"&gt;Q2 2011: Składamy produkty do kupy&lt;/span&gt;
Czyli jak to wszystko razem pracuje.
&lt;/td&gt;
&lt;td&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-88yddHj-Hmg/Tg2nVoNspgI/AAAAAAAAANA/EjBrW_TZx8E/s1600/9webinars.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 210px; height: 158px;" src="http://2.bp.blogspot.com/-88yddHj-Hmg/Tg2nVoNspgI/AAAAAAAAANA/EjBrW_TZx8E/s400/9webinars.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5624335499669579266" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2500007058363732177?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2500007058363732177/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2500007058363732177&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2500007058363732177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2500007058363732177'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/07/powrot-zielonego-net-ninja.html' title='Powrót zielonego .Net Ninja'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-gjTNciiYFfY/Tg2gRjllbRI/AAAAAAAAAL4/URlEEdLck0I/s72-c/.netNinja.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2580078795741983174</id><published>2011-06-30T23:30:00.000+02:00</published><updated>2011-06-30T23:30:10.497+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wszystko i nic'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Equal override</title><content type='html'>&lt;b&gt;Dlaczego nie lubię &lt;span style="color: blue;"&gt;override Equal&lt;/span&gt;?&lt;/b&gt;
&lt;span class="fullpost"&gt;  

Wszystko jest dla ludzi. Pewnie się nawet zbłaźnię tą opowieścią :]&lt;br/&gt;
Ostatnio poszukiwałam błędu w kodzie, w którym przeciążone były funkcje Equals (o czym dowiedziałam się po znacznym czasie spędzonym z debuggerem), a czasem także ==. Błąd okazał się dość paskudny bo był nieprzewidywalny. Problem był po dodaniu elementu do kolekcji - nagle zwracane były nieprawidłowe elementy z kolekcji.
&lt;br/&gt;
Na pierwszy rzut oka Equals wyglądał dobrze, zgodnie z zasadami 
&lt;a href="http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx"&gt;zalecanymi przez msdn&lt;/a&gt;. Dodatkowo sprawdzana była zgodność referencji mniej więcej w tym tonie (pominęłam kwestie nulli):
&lt;pre name="code" class="brush:c-sharp;"&gt;
    public class Person
    {
        private long _ID;
        public long ID
        { get { return _ID; } set { _ID = value; } }

        private string _Name;
        public string Name { get { return _Name; } set { _Name = value; } }

        public override bool Equals(object obj)
        {
            //obie alternatywy działają równie dobrze
            if (base.Equals(obj))//Object.ReferenceEquals(this, obj))
            {
                return true;
            }
            else
            {
                return this.Name == (obj as Person).Name;
            }
        }
    }
&lt;/pre&gt;
Wszystko będzie dobrze jeśli zadbamy o unikalność Name, w kodzie który poprawiałam unikalność nie była zachowana, dlatego wyniki były niezgodne z oczekiwaniami dla nowych elementów listy (w przeciwnym przypadku działał bazowy Equal porównujący referencje).

&lt;pre name="code" class="brush:c-sharp;"&gt;
//troche danych testowych, ID zgadza się z indexem w liście.            
            Person expectedOla = new Person() { ID = 3, Name = "Ola" };
            Person expectedAla = new Person() { ID = 2,Name = "Ala" };
            List&lt;Person&gt; p =
            new List&lt;Person&gt;()
            {
                new Person() { ID = 0,Name = "Ala" },
                new Person() { ID = 1,Name = "Ola" },
                expectedAla,
                expectedOla
            };
var iola = p.IndexOf(expectedOla)
//iola == 1
&lt;/pre&gt;
Całkiem oczywisty wynik skoro porównujemy Name, no ale przecież porównujemy także referencje! Jednak kiedy referencja się nie zgadza wracamy do porównania Name. IndexOf jak pisze &lt;a href="http://msdn.microsoft.com/en-us/library/e4w08k17.aspx"&gt;msdn&lt;/a&gt; działa od początku listy porównując każdy element - więc znajduje Olę pod 1. Tak naprawdę p.IndexOf(new Person()) po dekompilacji jakimś sprytnym narzędziem daje:
&lt;pre name="code" class="brush:c-sharp;"&gt;
[System.Runtime.TargetedPatchingOptOutAttribute(@"Performance critical to inline across NGen image boundaries")]
public virtual int IndexOf(T item) {
  return Array.IndexOf&lt;T&gt;(this._items, item, 0, this._size);
}
&lt;/pre&gt;

Na pewno używając jakieś funkcji warto było by dla przypomnienia sięgnąć do MSDNa. Ja w większości przypadków opieram się niestety na intelisens (choć ostatnio musiało się to zmienić) - mimo że w większości przypadków to wystarcza, jednak tam nie znajdziemy informacji że IndexOf bazuje na funkcji Equals, a jeśli jest ona przeciążona bazuje na jej bieżącym przeciążeniu.
&lt;br/&gt;
&lt;br/&gt;

Koniec końców musimy być uważni pisząc kod, a potem go naprawiając. Nie chodzi o to żeby fajnie coś się samo rzutowało, porównywało i inne bajery. Owszem jest to fajne, nawet w odkrywczym debugowaniu, jednak termin nie czeka na 'fajne. A nowa osoba w projekcie niekoniecznie będzie wiedzieć o jakimś przeciążeniu i mogą generować się błędy (oczywiście że błędy tak jak bałagan czy wiry w zlewie robią się same :]) bardzo pracochłonne w namierzeniu. Osobiście jestem za jakąś inną funkcją może CompareTo? ale na pewno taką którą łatwo się refaktoryzuje, wyszukuje i zmienia (a to przecież robi się ciągle i to często w kółko w zależności od klienta) przez cały system nie zastanawiając się czy dodatkowo jakaś funkcja .Netowa na niej nie bazuje. 
&lt;br/&gt;
&lt;br/&gt;
Jednak nie jestem absolutnym przeciwnikiem. Bardzo przydatne jest przeciążenie Equals dla np słowników - obiektów w miarę rzadko zmieniających swoje wartości i na pewno rzadko zmieniających strukturę (słowniki zazwyczaj nie zmieniają się wiele przez całe życie projektu, przynajmniej tak wynika z mojego doświadczenia :] ). Przeciążenie Equals zagwarantuje nam możliwość łatwiejszego używania takich obiektów np w ComboBoxach.
&lt;br/&gt;
Wszystko jest dla ludzi, ale - jak jeże - ostrożnie
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2580078795741983174?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2580078795741983174/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2580078795741983174&amp;isPopup=true' title='Komentarze (5)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2580078795741983174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2580078795741983174'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/06/equal-override.html' title='Equal override'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-4247552891051277919</id><published>2011-04-14T01:18:00.002+02:00</published><updated>2011-04-14T01:30:38.401+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wszystko i nic'/><title type='text'>Re-sizing a VirtualBox Virtual Disk</title><content type='html'>Dawno dawno temu za górami za lasami przeinstalowywanie systemu to był chleb powszedni. Ale człowiek (znaczy ja) z biegiem lat robi się bardzo leniwy. &lt;br/&gt;
&lt;b&gt;Co zrobić gdy okazuje się że założony rozmiar dysku nie wystarcza? &lt;/b&gt;&lt;br/&gt;
Powinno być przecież łatwe rozwiązanie.&lt;br/&gt;
Większość wpisów na forum VirtualBox prowadzi w pole, jednak znalazłam jeden który po długich bojach przyniósł większy dysk (szkoda że fizycznego nie da się tak po prostu rozciągnąć).
&lt;br/&gt;
&lt;a href="http://www.modhul.com/2008/10/21/re-sizing-a-virtualbox-virtual-disk-image-file/"&gt;Opis zwiększania rozmiaru dysku.&lt;/a&gt;

&lt;br/&gt;
Opisany w poście programik jest naprawdę sprytny (przenoszenie 20G na 60G trwało 19 minut), lekki i łatwy w użyciu.&lt;br/&gt;&lt;br/&gt;
Dodam od siebie że pierwsze uruchomienie systemu zakończyło się błędem ponieważ nie stworzyła się tablica MBR, trzeba było odpalić instalkę systemu i wykonać naprawianie - na szczęście 'zrobiło się to samo' a potem problemów już nie było.&lt;br/&gt;
&lt;span class="fullpost"&gt;


&lt;!--
n my previous post I extolled the virtues of Sun’s desktop virtualisation software, VirtualBox. One thing niggled me though – I couldn’t easily expand a Virtual Disk Image (VDI) and was regularly reaching the space limits of the modest 20Gb disks I was creating; I needed an easy way of expanding disks before I could use it as my main virtualisation platform and felt comfortable in recommending it to my readers.

Given that there is very little information out there on how to perform this task – apart from a single obscure forum post – here is my attempt to walk you through the process of expanding a virtual disk image. This guide assumes that you are trying to expand a disk configured with Windows, however the procedure should be pretty much the same for a Linux/OpenSolaris etc. based disk.

Getting Started

•Ensure that the Virtual Machine that uses the disk you want to re-size is shutdown.
•Remove any snapshots you may have – VirtualBox can go a bit wonky when re-sizing a VDI with snapshots attached (thank to Darren for pointing this one out).
•Take a backup of your VDI that you want to resize (by copying and pasting the .vdi file in Windows Explorer) – if we mess our resize up we can recover back to this backup.
•While the VDI file is copying, download the latest stable release of the gparted Live CD ISO from Sourceforge (approx 95Mb).
•While the ISO is downloading, create a new empty Virtual Disk in the VirtualBox console that is the size of the larger disk you need.
•Attach the new disk to your virtual machine that needs its disk expanding as the slave disk.
•Once the System Rescue CD download has completed, mount the ISO on the virtual machine CD drive.
Starting the Disk Image Utility

•Boot the virtual machine from the mounted ISO – you may need to reconfigure your VM to ensure that you boot from the CD-ROM drive before the HDD, so change the VM settings as shown below or hit F12 at boot and change there (given that VirtualBox is currently under development, the screenshot below will always be out of date, but I’m sure you get the idea ;-):


•During the boot process the gparted Live CD will prompt you to select the correct keymap – if you are using a QWERTY keyboard, simple select the ‘Don’t Touch Kepmap’ option; next, you will be prompted for the language settings to be used – select the appropriate language code, in my case ’02′ for British English; finally, you will be prompted for the X-Windows mode – select ’0′ to automagically start gparted in an X-Windows session.
•Once gparted starts, you will be presented with a graphical representation of your disks – left-click the left-to-right bar named /dev/sda1 (your primary hard disk that is to be expanded) and then click on the Copy icon.
•Select the drop-down-box to the right of the tool-bar and select the second (currently empty) disk – /dev/sdb (possibly /dev/hdb in your environment), the graphical representation of your disks will change to show you the second slave disk which is currently empty. Click on the Paste icon.
•gparted will will prompt you that all data on the new partition will be erased and if you’re happy, subsequently prompt you on how the disk should be formatted. For a Windows environment, select MSDOS (this will give you an NTFS partition, trust me!).

•gparted will finally present you with a slider dialog indicating the desired size of the new disk. Drag the slider to the right to select the maximum size of the new partition on this new disk (I’d just drag it so the partition consumes the whole disk), as shown in the screenshot below:


•Click the Apply icon, you’ll be presented with something along the lines of the screenshot below as the contents of the source disk are copied to the new, larger, disk:


•Once the copy has completed (approx. 35 mins to create a 30Gb disk from an original 20Gb disk), you will need to mark the new disk as bootable (if this is to be a bootable partition – if not, simply skip the next step).
•To mark the partition as bootable, right-click the graphical representation of the new disk and left-click Manage Flags. In the dialog that appears, select Boot and click Ok to close. gparted will apply the necessary flag and re-scan your disks.
•Close gparted and click the Exit icon to shutdown the system.
Completing the Re-Sizing

•Once the virtual machine has powered off, re-configure the hard disks to use the newly created/copied disk as the primary and remove the old primary disk from the system; finally, unmount the System Rescue ISO from the CD-ROM.
•Power on your new VM and you should be presented with the the usual Windows boot sequence; if you are just presented with a black screen with a flashing cursor at the top left-hand corner of the screen, there isn’t a boot sector on the disk, so restart gparted and add the boot flag as directed above.
•Hopefully, your virtual machine will start without issue. Windows may perform a check of the disk during boot. Once logged-in, open Windows Explorer and confirm that the newly created drive is the new larger size.
The procedure described above has been tested on Windows Server 2003 and works without issue (although the first time around I forgot to apply the boot flags…), so it should work seamlessly on Windows XP, Vista and Windows Server 2008.

I appreciate that this procedure does involve running a flavour of Linux to acheive the desired results, however its very straightforward and shouldn’t be off putting to a Linux novice.



Read more: http://www.modhul.com/2008/10/21/re-sizing-a-virtualbox-virtual-disk-image-file/#ixzz1JRstpzLe --&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-4247552891051277919?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/4247552891051277919/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=4247552891051277919&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4247552891051277919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4247552891051277919'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/04/re-sizing-virtualbox-virtual-disk.html' title='Re-sizing a VirtualBox Virtual Disk'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-791211474834294482</id><published>2011-04-09T20:00:00.012+02:00</published><updated>2012-01-10T20:00:33.244+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>2nd Silesian Code Camp</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-t3DsFIr5UA0/TaCtk3emD8I/AAAAAAAAAKQ/wJEgjKBu8DQ/s1600/Polecam2ndSilesianCodeCamp180x200.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 180px; height: 200px;" src="http://4.bp.blogspot.com/-t3DsFIr5UA0/TaCtk3emD8I/AAAAAAAAAKQ/wJEgjKBu8DQ/s400/Polecam2ndSilesianCodeCamp180x200.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5593661586073325506" /&gt;&lt;/a&gt;

&lt;span class="fullpost"&gt;
To już trzeci mój CodeCamp, nie wiedzieć czemu pierwszy śląski. Mam wrażenie że coraz to młodsi ludzie pojawiają się na takich spotkaniach - a myślałam że nie starzeje się aż tak szybko ;)&lt;br/&gt;&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Idea &lt;/span&gt;&lt;br/&gt;
CodeCamp to ogólnoświatowa impreza organizowana pod hasłem By and For the developer community. Od samego początku CodeCamp organizowany jest przez pasjonatów i dla pasjonatów zgromadzonych w tzw. społeczności programistów.
&lt;br/&gt;&lt;br/&gt;
Osobiście bardzo lubię Code Campy. Poziom sesji jest zawsze wysoki, często pojawiają się prelegenci których nie spotyka się często na zwykłych spotkaniach i ta otoczka organizacyjna - duża sala dużo ludzi. Mmmm. Ja zawsze jestem zachwycona. Nie mówiąc już o tym że zazwyczaj wybieram sesje w tematach o których nie mam pojęcia lub moje pojęcie jest bardzo blade - już nie raz okazywało się że taka jedna godzinna sesja może być dzwonem w odpowiednim kościele w dużo późniejszym czasie gdy przychodzi zabrać się za temat w szczegółach.&lt;br/&gt;
Jednak na każdym Code Campie ludzie gadają między sobą i często mam wrażenie że nie są zadowoleni. Czasem zastanawiam się czy to cecha narodowa polaków? Podobno na wyjazdach zagranicznych też tak jest że z Polaka wychodzi maruda;). &lt;br/&gt;
Gdyby chcieć się przyczepić to można by powiedzieć że sesje były zbyt wyspecjalizowane, że nie było darmowych ciastek i kawy na pierwszej przerwie [ale był RedBull i ładne panie go roznoszące, a ciastka na ostatniej przerwie były od samego prezesa Kamsoftu :)] a klimatyzacja za słabo działała [przynajmniej raz nie przemarzłam na kość] no i podobno w męskiej toalecie nieświeżo pachniało (a na ścianie ktoś napisał głupi kaowiec - nie czekać, to nie ten film!) [a w damskiej na takich spotkaniach jest zawsze luz i zapas papieru ;)].&lt;br/&gt;
Wróćmy więc do idei&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Idea &lt;/span&gt;&lt;br/&gt;
CodeCamp to ogólnoświatowa impreza organizowana pod hasłem By and For the developer community. Od samego początku CodeCamp organizowany jest przez pasjonatów i dla pasjonatów zgromadzonych w tzw. społeczności programistów.
&lt;br/&gt;&lt;br/&gt;
Dość elaboratu o emocjonalnym podejściu do sprawy przejdźmy do sesji na których byłam.&lt;br/&gt;&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Co, jak i kiedy? IN, NOT IN, EXISTS, NOT EXISTS – praktyczny poradnik - Damian Widera&lt;/span&gt;
Nie jestem dobra z SQLa, ba często nie wiem co się do mnie mówi w tym języku, jednak sesja była o aspektach praktycznych - co szybciej i sprawniej działa i czego warto używać. Nie ma się nad czym zastanawiać trzeba usiąść nad kodem z tej sesji i dokładnie zapamiętać! Miłym zaskoczeniem była sekcja 'jak czas pozwoli' w której Damian mówił o tym co mi już bliższe a mianowicie wydajności aplikacji pisanej w C# a korzystającej z jakiejś technologi pośredniej dostępu do danych. Damian mówił o Entity Frameworku, który miał ułatwiać programistom do danych, a tymczasem produkuje takie zapytania że z pewnością kiedyś trzeba będzie pochylić się nad kwestią wydajności. [Entity Framework w swoim dziele nie jest odosobniony ;)]&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Hakowanie Kinect - Szymon Kobalczyk&lt;/span&gt;
Wszyscy mówią że po Szymonie ciężko pokazać coś fajniejszego bo brakuje efektu wow. Trudno się nie zgodzić z tym stwierdzeniem po tej sesji. Troszkę o tym co to Microsoft znowu wykupił, jaki algorytm wyuczył (używając potężnych zasobów nie tylko sprzętowych), jak to ślicznie sprzedaje... Ale zaraz to faktycznie działa, potrafi budować trójwymiarowy obraz, śledzić graczy i ich tło, ustalać odległość i parę innych fajnych rzeczy. Być może póki co jest kolejną zabawką ale jeśli dołączyć do tego wyobraźnie developerów ... chyba trzeba się zastanowić jak daleko nam do interfejsów z raportu mniejszości.&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;MVVM i Windows Phone 7 - jak i po co? - Tomasz Wiśniewsk&lt;/span&gt;
Kolejny wzorzec projektowy - jak się o nich słucha to z jednej strony ma się zrażenie że są modne, że wszędzie się pojawiają, z drugiej jak się zastanowić to i tak ich używamy nawet o tym nie wiedząc. Tomek bardzo fajnie opowiedział o MVVM pokazując mimochodem parę ułatwiających życie drobiazgów w VS i przypominając o &lt;a href="http://www.codeplex.com/"&gt;CodePlex&lt;/a&gt;. Od razu przychodzi na myśl porównanie z MVC ;) Mnie osobiście w przykładać MVVM zabrakło jakiegoś updatu czy insertu, ale przeciwnikiem zawsze jest czas.
&lt;br/&gt;
&lt;br/&gt;
Jak dla mnie bomba ;) czekam na kolejny CodeCamp, a tymczasem niebawem &lt;a href="http://geeksontour.pl/pl/Homepage.aspx"&gt;Geek On Tour&lt;/a&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-791211474834294482?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/791211474834294482/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=791211474834294482&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/791211474834294482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/791211474834294482'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/04/2nd-silesian-code-camp.html' title='2nd Silesian Code Camp'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-t3DsFIr5UA0/TaCtk3emD8I/AAAAAAAAAKQ/wJEgjKBu8DQ/s72-c/Polecam2ndSilesianCodeCamp180x200.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2204737607538912521</id><published>2011-04-08T15:15:00.009+02:00</published><updated>2011-04-08T23:51:13.244+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC2 What's new part 3.</title><content type='html'>&lt;b&gt;Areas czyli obszary  &lt;/b&gt;
&lt;br/&gt;
Areas pozwalają na rozbicie aplikacji na obszary. 
&lt;span class="fullpost"&gt;
Każdy z obszarów będzie miał swój zestaw kontrolerów, widoków i routing.
Wszystkie obszary mogą nadal korzystać z katalogu Shared, nadal możemy mieć główny obszar (ten który był dostępny do tej pory).&lt;br/&gt;
Dodanie obszaru jest proste:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-L4JrFcmC24A/TZ8TPg2feyI/AAAAAAAAAJw/Sq6cTnpV3PU/s1600/mvcAreaAdd.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 294px;" src="http://3.bp.blogspot.com/-L4JrFcmC24A/TZ8TPg2feyI/AAAAAAAAAJw/Sq6cTnpV3PU/s320/mvcAreaAdd.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5593210419454901026" /&gt;&lt;/a&gt;
Utworzony zostanie katalog &lt;span style="font-weight:bold;"&gt;Areas&lt;/span&gt; 
a w nim nasz nowy obszar oraz nowy zestaw katalogów ze strukturą MVC.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-PRgAaL3zJZc/TZ8V0NRgngI/AAAAAAAAAJ4/mmWHg6soe1k/s1600/mvcarea1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 154px; height: 320px;" src="http://2.bp.blogspot.com/-PRgAaL3zJZc/TZ8V0NRgngI/AAAAAAAAAJ4/mmWHg6soe1k/s320/mvcarea1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5593213248877927938" /&gt;&lt;/a&gt;
Została również utworzona klasa typu &lt;span style="color:blue;"&gt;AreaRegistration&lt;/span&gt;. Region zostanie automatycznie zarejestrowany dzięki &lt;span style="color:blue;"&gt;AreaRegistration.RegisterAllAreas();&lt;/span&gt;
który jest wywoływany na Application_Start()

&lt;pre name="code" class="brush:c-sharp;"&gt;
public class SomeNewAreaAreaRegistration : AreaRegistration
{
   /// unikalna nazwa obszaru, wykorzystywana do nawigacji
    public override string AreaName
    {
        get
        {
            return "SomeNewArea";
        }
    }

    /// rejestrujemy routing dla danego obszaru
    /// nie ma domyślnego kontrolera, jednak możemy go bez problemu dodać
    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "SomeNewArea_default",
            "SomeNewArea/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
            ,new string[]{"Controllers.SomeNewArea"}
        );
    }
}
&lt;/pre&gt;

W obszarach mogą powtarzać się nazwy kontrolerów, jednak jeśli w tej chwili dodamy sobie do obszaru SomeNewArea kontroler Home dostaniemy błąd ponieważ defaultowy routing nie będzie wiedział gdzie szukać. Musimy mu więc powiedzieć
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-po2l0kpZyrE/TZ9sWskVm0I/AAAAAAAAAKA/Jp2nKAVVKIU/s1600/mvcarearouting.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 93px;" src="http://1.bp.blogspot.com/-po2l0kpZyrE/TZ9sWskVm0I/AAAAAAAAAKA/Jp2nKAVVKIU/s320/mvcarearouting.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5593308399393938242" /&gt;&lt;/a&gt;
W moim przypadku namespace gdzie znajduje się domyślny kontroler Home to Controllers. Moim zdaniem wydzielenie kontrolerów do osobnej dll zwiększa przejrzystość kodu, a z obszarami jeszcze bardziej.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   routes.MapRoute(
     "Default", // Route name
     "{controller}/{action}/{id}", // URL with parameters
     new { controller = "Home", action = "Index", id = UrlParameter.Optional}
     , new string[]{"Controllers"}
     );
}
&lt;/pre&gt;
Teraz możemy dostać się wszędzie wpisując adres, jednak jeśli przejdziemy do obszaru SomeNewArea przestanie działać menu - a to dlatego że obecny zapis menu wskazuje na linki w tym tym samym obszarze a nie obszarze głównym tak jakbyśmy się tego spodziewali.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 &lt;ul id="menu"&gt;              
   &lt;li&gt;&lt;%: Html.ActionLink("Home", "Index", "Home")%&gt;&lt;/li&gt;
   &lt;li&gt;&lt;%: Html.ActionLink("About", "About", "Home")%&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/pre&gt;
Musimy dołączyć informacje o obszarze. Jeśli chcemy się dostać do 'głównego' obszaru nazwę pozostawiamy pustą.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 &lt;ul id="menu"&gt;
  &lt;li&gt;
   &lt;%: Html.ActionLink("Home", "Index", "Home", new {area = ""}, null)%&gt;
  &lt;/li&gt;
  &lt;li&gt;
   &lt;%: Html.ActionLink("About", "About", "Home", new {area = ""}, null)%&gt;
  &lt;/li&gt;
  &lt;li&gt;
   &lt;%: Html.ActionLink("HomeSomeNew", "Index", "Home", 
                              new { area="SomeNewArea"}, null)%&gt;
  &lt;/li&gt;
 &lt;/ul&gt;           
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2204737607538912521?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2204737607538912521/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2204737607538912521&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2204737607538912521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2204737607538912521'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/04/mvc2-whats-new-part-3.html' title='MVC2 What&apos;s new part 3.'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-L4JrFcmC24A/TZ8TPg2feyI/AAAAAAAAAJw/Sq6cTnpV3PU/s72-c/mvcAreaAdd.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3519968247264001529</id><published>2011-04-07T13:33:00.009+02:00</published><updated>2011-04-07T15:18:59.812+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC2 What's new part 2.</title><content type='html'>&lt;b&gt;Achronous Controller - asynchroniczne kontrolery&lt;/b&gt;
&lt;br/&gt;
Asynchroniczne wywołania mogą poprawić wydajność aplikacji, jednak zawsze powodują dużo większe skomplikowanie kodu.&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ee728598(v=VS.100).aspx#Y1728"&gt;W artykule na MSDN&lt;/a&gt; wymienione jest kilka punktów kiedy warto używać asynchronicznych wywołań jak np. długo trwające operacje wejścia-wyjścia, inne długo trwające operacje, czy nastawienie na wielowątkowość.&lt;br/&gt;
&lt;br/&gt;
Klasyczny kontroler (z klasycznym przykładem) wywołania z jakiegoś serwisu:
&lt;pre name="code" class="brush:c-sharp;"&gt;
public class HomeController : Controller
{
    public ActionResult Index()
    {
        var client = new News.NewsServieceClient();
        var news = client.GetNewsList();
        return View(news);
    }
}
&lt;/pre&gt;
&lt;br/&gt;
Aby stworzyć wersje asynchroniczną:
&lt;ul&gt;
&lt;li&gt; dziedziczymy po &lt;span style="color:blue;"&gt;AsyncController &lt;/span&gt;zamiast zwykłego Controller&lt;/li&gt;

&lt;li&gt; funkcję &lt;span style="font-style:italic;"&gt;Index&lt;/span&gt; (czy też każdą inną) rozbijamy na dwie:&lt;br/&gt;
&lt;span style="color:blue;"&gt;&lt;span style="font-style:italic;"&gt;Index&lt;/span&gt;Async&lt;/span&gt; &lt;br/&gt;
&lt;span style="color:blue;"&gt;&lt;span style="font-style:italic;"&gt;Index&lt;/span&gt;Completed&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;wymieniamy wnętrzności funkcji aby stworzyć wersje async&lt;/li&gt;
&lt;li&gt;używamy &lt;span style="color:blue;"&gt;AsyncManager&lt;/span&gt;&lt;br/&gt;
Gdy wywołujemy operacje inkrementujemy ilość operacji w AsyncManager za pomocą: &lt;br/&gt;
&lt;span style="color:blue;"&gt;AsyncManager.OutstandingOperations.Increment();&lt;/span&gt; &lt;br/&gt;
Jeśli były by jeszcze jakieś operacje oprócz przykładowego pobierania wiadomości np. pobieranie wiadomości sportowych, 
również zinkrementowalibyśmy &lt;span style="color:blue;"&gt;OutstandingOperations&lt;/span&gt; a AsyncManager wiedziałby że są to dwie operacje. &lt;br/&gt;
Kiedy zostanie obsłużona funkcja Completed danej operacji wywołamy&lt;br/&gt;
&lt;span style="color:blue;"&gt;AsyncManager.OutstandingOperations.Decrement();&lt;/span&gt;&lt;br/&gt;
Tym sposobem kiedy zakończą się wszystkie operacje AsyncManager będzie wiedział że należy wywołać &lt;span style="font-style:italic;"&gt;IndexCompleted&lt;/span&gt;.            
&lt;/li&gt;
&lt;/ul&gt;

A oto wersja asynchroniczna, z dodatkowymi wyjaśnieniami.
&lt;pre name="code" class="brush:c-sharp;"&gt;
  public class HomeController : AsyncController
    {
        //brak zwracanej wartości - tylko przygotowanie operacji
        public void IndexAsync()
        {
            var client = new NewsServiceClient();
            
            //musimy obsłużyć Completed z serwisu który wołamy 
            client.GetNewsItemsCompleted += (sender, args) =&gt;
            {
                // rezultat wykonania przekazujemy do AsyncManager
                // parametry zostaną przekazane do fukcji "IndexCompleted"  
                AsyncManager.Parameters["news"] = args.Result;
                //Informujemy AsyncManager o obecnej ilości operacji 
                AsyncManager.OutstandingOperations.Decrement();
            };

            //Informujemy AsyncManager o obecnej ilości operacji 
            AsyncManager.OutstandingOperations.Increment();
            //serwis który wołamy oczywiście musi obsługiwać wywołania asynchroniczne
            client.GetNewsItemsAsync();
        }
        
        /// funkcja Completed wykonuje jakąś akcję (generuje widok)
        /// na podstawie parametru przekazanego z operacji async
        public ActionResult IndexCompleted(object news)
        {
            return View(news);
        }
    }

&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3519968247264001529?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3519968247264001529/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3519968247264001529&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3519968247264001529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3519968247264001529'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/04/mvc2-whats-new-part-2.html' title='MVC2 What&apos;s new part 2.'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-1304737249533345021</id><published>2011-03-29T23:08:00.009+02:00</published><updated>2011-03-30T00:22:21.615+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC2 What's new part 1.</title><content type='html'>&lt;b&gt;MVC 2 nowości.  &lt;/b&gt;
&lt;br/&gt;
MVC2 ujrzało światło dzienne już jakiś czas temu. Ba już dwa miesiące temu doczekaliśmy się MVC3. Pora uaktualnić wiedzę. Więc krok za krokiem - co nowego w MVC2.
&lt;span class="fullpost"&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;1. Opcjonalne paramety.&lt;/span&gt;&lt;br/&gt;
.NET 4 wprowadza opcjonalne parametry. MVC2 może czerpać korzyści z tego faktu np.

&lt;pre name="code" class="brush:c-sharp;"&gt;
public ActionResult Index (int Page = 1)
{
  //
}
&lt;/pre&gt;
&lt;br/&gt;
&lt;b&gt;2. Dostępne są nowe snipety &lt;/b&gt; przyspieszające wklepywanie kodu.&lt;br/&gt;
&lt;b&gt;3. Action selectors&lt;/b&gt;&lt;br/&gt;
Action selector filters to określenie atrybutów nadawanych metodom kontrolera, na które zwraca uwagę &lt;span style="color:blue;"&gt;IActionInvoker &lt;/span&gt;szukając metody do wykonania odpowiadającej żądaniu.&lt;br/&gt;
W MVC1 atrybutów było dwa:&lt;br/&gt;
&lt;span style="color:blue;"&gt;ActionName &lt;/span&gt;- nadpisujący nazwę metody &lt;br/&gt;
&lt;span style="color:blue;"&gt;AcceptVerbs &lt;/span&gt;- ogranicza wywołanie metody do wyspecyfikowanego HttpVerb.

&lt;pre name="code" class="brush:c-sharp;"&gt;
[ActionName("Modyfy")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contact)
{
}
&lt;/pre&gt;
HttpVerbs.Post odpowiada tylko na wywołania Post, które powinny być zarezerwowane dla metod edytujących dane po stronie serwera.&lt;br/&gt;
Operacje Get powinny unikać modyfikacji danych, ponieważ mogą one być cachowane.&lt;br/&gt;

W MVC2 zapis został uproszczony i mamy HttpPost, HttpGet, HttpPut, HttpDelete, do wykorzystania dwóch ostatnich wymagany jest &lt;span style="color:blue;"&gt;HttpMethodOverride &lt;/span&gt;gdyż standardowo przeglądarki posługują się tylko Get i Post.
&lt;pre name="code" class="brush:c-sharp;"&gt;
[HttpPost]
public ActionResult Edit(Contact contact)
{
}
&lt;/pre&gt;
&lt;b&gt;RequiredHttps&lt;/b&gt; może zostać zastosowany na poziomie całego kontrolera bądź dowolnej metody - wykonuje redirect na SSLowy odpowienik strony. 

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-1304737249533345021?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/1304737249533345021/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=1304737249533345021&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1304737249533345021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1304737249533345021'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/03/mvc2-whats-new-part-1.html' title='MVC2 What&apos;s new part 1.'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-7423819187200655602</id><published>2011-03-05T20:52:00.009+01:00</published><updated>2011-03-05T22:20:30.080+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Multidelete z użyciem zmiennej tablicowej</title><content type='html'>&lt;b&gt;Przekazanie wielu parametrów na raz do procedury składowanej można załatwić zmiennymi tablicowymi - Table Valued Parameter. &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Prezentuje przypadek usunięcia wielu elementów według ich idków, jednak mechanizm jest identyczny np dla insertów updatów czy dowolnych operacji - jednak wtedy zazwyczaj potrzebna są bardziej rozbudowane typy danych (tutaj mam typ który ma tylko jedną kolumne).&lt;br/&gt;
Typ z jedną kolumną
&lt;pre name="code" class="brush:sql;"&gt;
CREATE TYPE [dbo].[_ContactIDs] AS TABLE(
 [ID] [bigint] NOT NULL
)
&lt;/pre&gt;
Procedurka która przyjmuje zmienna tablicową i wykorzystuje do operacji usuwania.
&lt;pre name="code" class="brush:sql;"&gt;
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[ContactMultiDelete]
( 
 @TableVariable _ContactIDs READONLY
)
AS
begin tran

delete  from Contact 
from Contact a
inner join @TableVariable t on t.ID = a.ID

commit tran
&lt;/pre&gt;

No i fragment kodu C# wywołującego procedurkę za pomocą ADO. &lt;be/&gt;
Ważne jest aby DataTable przekazywany do procedurki nazywał się jak zmienna która procedurka oczekuje.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 List&lt;Contact&gt; toDelete = GetListOfContactToDelete(); 

 //dataTable musi się nazywać tak jak typ tablicowy w sqlu
 DataTable dt = new DataTable("_ContactIDs");
 dt.Columns.Add(new DataColumn("ID"));
 if (toDelete != null &amp;&amp; toDelete.Count &gt; 0)
 {
     //przerabiamy listę idków na DataTable
  toDelete.ToList().ForEach(a =&gt;
  {
   DataRow dr = dt.NewRow();
   dr["ID"] = a.ID;
   dt.Rows.Add(dr);
  });

 System.Data.SqlClient.SqlConnection sql1 = new System.Data.SqlClient.SqlConnection(connString);
 System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand("dbo.ContactMultiDelete", sql1);
 cmd1.CommandType = CommandType.StoredProcedure;
 //Parametr typu tablicowego
 System.Data.SqlClient.SqlParameter sp1 = cmd1.Parameters.AddWithValue("@TableVariable", dt);
 sp1.SqlDbType = SqlDbType.Structured;
 sql1.Open();
 cmd1.ExecuteNonQuery();
 sql1.Close();

&lt;/pre&gt;

&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Ale&lt;/span&gt;
&lt;br/&gt;
Nie byłabym sobą gdybym gdzieś nie znalazła ale. Nie wiem na ile to ale jest prawdziwe gdyż sama nie sprawdziłam, jednak jest cokolwiek niepokojące. &lt;br/&gt;
Mianowicie wywołania takie mogą powodować problemy wydajnościowe ze względu na każdorazowe kompilowanie planu wykonania procedury.&lt;br/&gt;
Tutaj więcej info:&lt;br/&gt;
&lt;a href="http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/9d498061-5cbf-49d7-83ea-72f5ddf5db6c"&gt;Using ADO.NET SqlDbType.Structured TVP (Table Valued Parameters) causes SQL Compilation for every call&lt;/a&gt;;&lt;br/&gt;
&lt;a href="http://www.sqlskills.com/BLOGS/BOBB/post/The-interesting-case-of-TVPs-and-plan-compilation.aspx"&gt;The interesting case of TVPs and plan compilation&lt;/a&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;a href="http://technet.microsoft.com/pl-pl/library/tabele-tymczasowe-i-zmienne-tablicowe-fakty-i-mity.aspx"&gt;I jeszcze na zakończenie mały art z technet o tablicach tymczasowych i zmiennych tablicowych&lt;/a&gt;






&lt;!-- to samo z hibernata http://stackoverflow.com/questions/3701364/nhibernate-sqldbtype-structured --&gt;
&lt;!--
------------------------------------------------------------------------------------------------- 
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OMG.ControllersInterfaces;
using NC.Framework.GUI.BaseForms;
using NC.Framework.BaseControllers;
using OMG.BusinessObjects;
using NC.Framework.BaseBusinessObjects;
using OMG.GUI.Forms.MediaPlan;
using NC.Framework.BaseControllersInterfaces.ControllersInterfaces;
using NC.Framework.GUI.Exceptions;
using System.Reflection;
using OMG.BusinessObjects.Common;
using System.Data;
using System.Data.SqlClient;

namespace OMG.Controllers
{
    public partial class MediaPlanController : BaseController, IMediaPlanController
    {
        #region Fill media plan adv cinema
        private MediaPlanAdvCinemaPriceList GenerateAdvCinemaPriceListObject(DataRow advRow, MediaPlan mediaPlan)
        {
            MediaPlanAdvCinemaPriceList ret = new MediaPlanAdvCinemaPriceList(mediaPlan.InstanceGUID);
            ret.MediaPlan = mediaPlan;
            #region properties copy

            for (int i = 0; i &lt; advRow.Table.Columns.Count; i++)
            {
                if (!advRow.IsNull(advRow.Table.Columns[i]) &amp;&amp; !advRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(advRow.Table.Columns[i].ColumnName, advRow[i]);
                }
            }

            if (advRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(advRow["ID"]);
            }

            if (advRow.IsNull("BuyUnitID"))
            {
                ret.BuyUnit = null;
            }
            else
            {
                ret.BuyUnit = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["BuyUnitID"]), DicType.BuyUnitCinema);
            }

            if (advRow.IsNull("CityID"))
            {
                ret.City = null;
            }
            else
            {
                ret.City = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CityID"]), DicType.City);
            }

            if (advRow.IsNull("CommunicationTypeID"))
            {
                ret.CommunicationType = null;
            }
            else
            {
                ret.CommunicationType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CommunicationTypeID"]), DicType.CommunicationType);
            }

            if (advRow.IsNull("CurrencyID"))
            {
                ret.Currency = null;
            }
            else
            {
                ret.Currency = CommonController.CurrencyDictionaryItemGet(Convert.ToInt64(advRow["CurrencyID"]));
            }

            if (advRow.IsNull("DayOfWeekID"))
            {
                ret.DayOfWeekid = null;
            }
            else
            {
                ret.DayOfWeekid = Convert.ToInt64(advRow["DayOfWeekID"]);
            }

            if (advRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (advRow.IsNull("MediumID"))
            {
                ret.Medium = null;
            }
            else
            {
                ret.Medium = m_MediumController.MediumGet(Session, (Convert.ToInt64(advRow["MediumID"])));
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("SubjectGUID"))
            {
                ret.SubjectGUID = null;
            }
            else
            {
                ret.SubjectGUID = Convert.ToString(advRow["SubjectGUID"]);
            }

            if (advRow.IsNull("MediaplanOtherAgenciesID"))
            {
                ret.MediaplanOtherAgenciesid = null;
            }
            else
            {
                ret.MediaplanOtherAgenciesid = Convert.ToInt64(advRow["MediaplanOtherAgenciesID"]);
            }

            if (advRow.IsNull("PricelistSpecificationID"))
            {
                ret.PriceListSpecification = null;
            }
            else
            {
                ret.PriceListSpecification = Helper.Get&lt;PriceListAdvCinema&gt;(Session, Convert.ToInt64(advRow["PricelistSpecificationID"]));
            }


            if (advRow.IsNull("PriceListID"))
            {
                ret.PriceList = null;
            }
            else
            {
                ret.PriceList = Helper.Get&lt;PriceList&gt;(Session, Convert.ToInt64(advRow["PriceListID"]));
            }

            if (advRow.IsNull("MultikinoID"))
            {

                ret.Multikino = null;
            }
            else
            {
                ret.Multikino = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["MultikinoID"]), DicType.Multikino);
            }

            if (advRow.IsNull("TimeLimitsID"))
            {
                ret.TimeLimits = null;
            }
            else
            {
                ret.TimeLimits = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["TimeLimitsID"]), DicType.TimeConstraints);
            }

            if (advRow.IsNull("ReasonOfCancellationID"))
            {
                ret.ReasonOfCancellation = null;
            }
            else
            {
                ret.ReasonOfCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonOfCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("ReasonForOrderCancellationID"))
            {
                ret.ReasonForOrderCancellation = null;
            }
            else
            {
                ret.ReasonForOrderCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonForOrderCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("TradeTermsID"))
            {
                ret.TradeTerms = null;
            }
            else
            {
                ret.TradeTerms = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsID"])));
            }

            if (advRow.IsNull("TradeTermsImplementationID"))
            {
                ret.TradeTermsImplementation = null;
            }
            else
            {
                ret.TradeTermsImplementation = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsImplementationID"])));
            }




            #endregion

            return ret;
        }
        private MediaPlanAdvCinemaShopping GenerateAdvCinemaShoppingObject(DataRow advRow, MediaPlan mediaPlan)
        {
            MediaPlanAdvCinemaShopping ret = new MediaPlanAdvCinemaShopping(mediaPlan.InstanceGUID);
            ret.MediaPlan = mediaPlan;
            #region properties copy

            for (int i = 0; i &lt; advRow.Table.Columns.Count; i++)
            {
                if (!advRow.IsNull(advRow.Table.Columns[i]) &amp;&amp; !advRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(advRow.Table.Columns[i].ColumnName, advRow[i]);
                }
            }

            if (advRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(advRow["ID"]);
            }

            if (advRow.IsNull("BuyUnitID"))
            {
                ret.BuyUnit = null;
            }
            else
            {
                ret.BuyUnit = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["BuyUnitID"]), DicType.BuyUnitCinema);
            }

            if (advRow.IsNull("CityID"))
            {
                ret.City = null;
            }
            else
            {
                ret.City = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CityID"]), DicType.City);
            }

            if (advRow.IsNull("CommunicationTypeID"))
            {
                ret.CommunicationType = null;
            }
            else
            {
                ret.CommunicationType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CommunicationTypeID"]), DicType.CommunicationType);
            }

            if (advRow.IsNull("CurrencyID"))
            {
                ret.Currency = null;
            }
            else
            {
                ret.Currency = CommonController.CurrencyDictionaryItemGet(Convert.ToInt64(advRow["CurrencyID"]));
            }

            if (advRow.IsNull("DayOfWeekID"))
            {
                ret.DayOfWeekid = null;
            }
            else
            {
                ret.DayOfWeekid = Convert.ToInt64(advRow["DayOfWeekID"]);
            }

            if (advRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (advRow.IsNull("MediumID"))
            {
                ret.Medium = null;
            }
            else
            {
                ret.Medium = m_MediumController.MediumGet(Session, (Convert.ToInt64(advRow["MediumID"])));
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("SubjectGUID"))
            {
                ret.SubjectGUID = null;
            }
            else
            {
                ret.SubjectGUID = Convert.ToString(advRow["SubjectGUID"]);
            }

            if (advRow.IsNull("MediaplanOtherAgenciesID"))
            {
                ret.MediaplanOtherAgenciesid = null;
            }
            else
            {
                ret.MediaplanOtherAgenciesid = Convert.ToInt64(advRow["MediaplanOtherAgenciesID"]);
            }

            if (advRow.IsNull("PricelistSpecificationID"))
            {
                ret.PriceListSpecification = null;
            }
            else
            {
                ret.PriceListSpecification = Helper.Get&lt;PriceListAdvCinema&gt;(Session, Convert.ToInt64(advRow["PricelistSpecificationID"]));
            }

            if (advRow.IsNull("PriceListID"))
            {
                ret.PriceList = null;
            }
            else
            {
                ret.PriceList = Helper.Get&lt;PriceList&gt;(Session, Convert.ToInt64(advRow["PriceListID"]));
            }

            if (advRow.IsNull("MultikinoID"))
            {
                ret.Multikino = null;
            }
            else
            {
                ret.Multikino = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["MultikinoID"]), DicType.Multikino);
            }

            if (advRow.IsNull("TimeLimitsID"))
            {
                ret.TimeLimits = null;
            }
            else
            {
                ret.TimeLimits = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["TimeLimitsID"]), DicType.TimeConstraints);
            }

            if (advRow.IsNull("FreeTypeID"))
            {
                ret.FreeType = null;
            }
            else
            {
                ret.FreeType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["FreeTypeID"]), DicType.FreeAdvType);
            }

            if (advRow.IsNull("PriceLevelID"))
            {
                ret.PriceLevel = null;
            }
            else
            {
                ret.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceLevelID"]), DicType.PriceLevel);
            }

            if (advRow.IsNull("ReasonOfCancellationID"))
            {
                ret.ReasonOfCancellation = null;
            }
            else
            {
                ret.ReasonOfCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonOfCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("ReasonForOrderCancellationID"))
            {
                ret.ReasonForOrderCancellation = null;
            }
            else
            {
                ret.ReasonForOrderCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonForOrderCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("TradeTermsID"))
            {
                ret.TradeTerms = null;
            }
            else
            {
                ret.TradeTerms = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsID"])));
            }

            if (advRow.IsNull("TradeTermsImplementationID"))
            {
                ret.TradeTermsImplementation = null;
            }
            else
            {
                ret.TradeTermsImplementation = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsImplementationID"])));
            }




            #endregion

            if (advRow.IsNull("IsBonusFree")) { ret.IsBonusFree = null; }
            else { ret.IsBonusFree = System.Convert.ToBoolean(advRow["IsBonusFree"]); }
            if (advRow.IsNull("IsInvoice")) { ret.IsInvoice = null; }
            else { ret.IsInvoice = System.Convert.ToBoolean(advRow["IsInvoice"]); }
            if (advRow.IsNull("IsBonus")) { ret.IsBonus = null; }
            else { ret.IsBonus = System.Convert.ToBoolean(advRow["PostbuyNotes"]); }
            if (advRow.IsNull("IsForBonus")) { ret.IsForBonus = null; }
            else { ret.IsForBonus = System.Convert.ToBoolean(advRow["IsForBonus"]); }
            if (advRow.IsNull("IsFree")) { ret.IsFree = null; }
            else { ret.IsFree = System.Convert.ToBoolean(advRow["IsFree"]); }
            if (advRow.IsNull("PercentFree")) { ret.PercentFree = null; }
            else { ret.PercentFree = System.Convert.ToDecimal(advRow["PercentFree"]); }
            if (advRow.IsNull("FreeVolume")) { ret.FreeVolume = null; }
            else { ret.FreeVolume = System.Convert.ToDecimal(advRow["FreeVolume"]); }
            if (advRow.IsNull("FreeTypeID"))
            { ret.FreeType = null; }
            else
            { ret.FreeType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["FreeTypeID"]), DicType.FreeAdvType); }
            if (advRow.IsNull("PriceLevelID"))
            { ret.PriceLevel = null; }
            else
            { ret.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceLevelID"]), DicType.PriceLevel); }

            return ret;
        }
        private MediaPlanAdvCinemaClient GenerateAdvCinemaClientObject(DataRow advRow, MediaPlan mediaPlan)
        {
            MediaPlanAdvCinemaClient ret = new MediaPlanAdvCinemaClient(mediaPlan.InstanceGUID);
            ret.MediaPlan = mediaPlan;
            #region properties copy

            for (int i = 0; i &lt; advRow.Table.Columns.Count; i++)
            {
                if (!advRow.IsNull(advRow.Table.Columns[i]) &amp;&amp; !advRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(advRow.Table.Columns[i].ColumnName, advRow[i]);
                }
            }

            if (advRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(advRow["ID"]);
            }

            if (advRow.IsNull("BuyUnitID"))
            {
                ret.BuyUnit = null;
            }
            else
            {
                ret.BuyUnit = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["BuyUnitID"]), DicType.BuyUnitCinema);
            }

            if (advRow.IsNull("CityID"))
            {
                ret.City = null;
            }
            else
            {
                ret.City = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CityID"]), DicType.City);
            }

            if (advRow.IsNull("CommunicationTypeID"))
            {
                ret.CommunicationType = null;
            }
            else
            {
                ret.CommunicationType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CommunicationTypeID"]), DicType.CommunicationType);
            }

            if (advRow.IsNull("CurrencyID"))
            {
                ret.Currency = null;
            }
            else
            {
                ret.Currency = CommonController.CurrencyDictionaryItemGet(Convert.ToInt64(advRow["CurrencyID"]));
            }

            if (advRow.IsNull("DayOfWeekID"))
            {
                ret.DayOfWeekid = null;
            }
            else
            {
                ret.DayOfWeekid = Convert.ToInt64(advRow["DayOfWeekID"]);
            }

            if (advRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (advRow.IsNull("MediumID"))
            {
                ret.Medium = null;
            }
            else
            {
                ret.Medium = m_MediumController.MediumGet(Session, (Convert.ToInt64(advRow["MediumID"])));
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("SubjectGUID"))
            {
                ret.SubjectGUID = null;
            }
            else
            {
                ret.SubjectGUID = Convert.ToString(advRow["SubjectGUID"]);
            }

            if (advRow.IsNull("MediaplanOtherAgenciesID"))
            {
                ret.MediaplanOtherAgenciesid = null;
            }
            else
            {
                ret.MediaplanOtherAgenciesid = Convert.ToInt64(advRow["MediaplanOtherAgenciesID"]);
            }

            if (advRow.IsNull("PricelistSpecificationID"))
            {
                ret.PriceListSpecification = null;
            }
            else
            {
                ret.PriceListSpecification = Helper.Get&lt;PriceListAdvCinema&gt;(Session, Convert.ToInt64(advRow["PricelistSpecificationID"]));
            }

            if (advRow.IsNull("PriceListID"))
            {
                ret.PriceList = null;
            }
            else
            {
                ret.PriceList = Helper.Get&lt;PriceList&gt;(Session, Convert.ToInt64(advRow["PriceListID"]));
            }

            if (advRow.IsNull("MultikinoID"))
            {
                ret.Multikino = null;
            }
            else
            {
                ret.Multikino = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["MultikinoID"]), DicType.Multikino);
            }

            if (advRow.IsNull("TimeLimitsID"))
            {
                ret.TimeLimits = null;
            }
            else
            {
                ret.TimeLimits = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["TimeLimitsID"]), DicType.TimeConstraints);
            }

            if (advRow.IsNull("FreeTypeID"))
            {
                ret.FreeType = null;
            }
            else
            {
                ret.FreeType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["FreeTypeID"]), DicType.FreeAdvType);
            }

            if (advRow.IsNull("PriceLevelID"))
            {
                ret.PriceLevel = null;
            }
            else
            {
                ret.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceLevelID"]), DicType.PriceLevel);
            }

            if (advRow.IsNull("ReasonOfCancellationID"))
            {
                ret.ReasonOfCancellation = null;
            }
            else
            {
                ret.ReasonOfCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonOfCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("ReasonForOrderCancellationID"))
            {
                ret.ReasonForOrderCancellation = null;
            }
            else
            {
                ret.ReasonForOrderCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonForOrderCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("TradeTermsID"))
            {
                ret.TradeTerms = null;
            }
            else
            {
                ret.TradeTerms = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsID"])));
            }

            if (advRow.IsNull("TradeTermsImplementationID"))
            {
                ret.TradeTermsImplementation = null;
            }
            else
            {
                ret.TradeTermsImplementation = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsImplementationID"])));
            }




            #endregion
            if (advRow.IsNull("IsInvoice")) { ret.IsInvoice = null; }
            else { ret.IsInvoice = System.Convert.ToBoolean(advRow["IsInvoice"]); }
            if (advRow.IsNull("IsBonus")) { ret.IsBonus = null; }
            else { ret.IsBonus = System.Convert.ToBoolean(advRow["PostbuyNotes"]); }
            if (advRow.IsNull("IsForBonus")) { ret.IsForBonus = null; }
            else { ret.IsForBonus = System.Convert.ToBoolean(advRow["IsForBonus"]); }
            if (advRow.IsNull("IsFree")) { ret.IsFree = null; }
            else { ret.IsFree = System.Convert.ToBoolean(advRow["IsFree"]); }
            if (advRow.IsNull("PercentFree")) { ret.PercentFree = null; }
            else { ret.PercentFree = System.Convert.ToDecimal(advRow["PercentFree"]); }
            if (advRow.IsNull("FreeVolume")) { ret.FreeVolume = null; }
            else { ret.FreeVolume = System.Convert.ToDecimal(advRow["FreeVolume"]); }
            if (advRow.IsNull("FreeTypeID"))
            { ret.FreeType = null; }
            else
            { ret.FreeType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["FreeTypeID"]), DicType.FreeAdvType); }
            if (advRow.IsNull("PriceLevelID"))
            { ret.PriceLevel = null; }
            else
            { ret.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceLevelID"]), DicType.PriceLevel); }

            return ret;
        }
        private MediaPlanAdvCinemaChimery GenerateAdvCinemaChimeryObject(DataRow advRow, MediaPlan mediaPlan)
        {
            MediaPlanAdvCinemaChimery ret = new MediaPlanAdvCinemaChimery(mediaPlan.InstanceGUID);
            ret.MediaPlan = mediaPlan;
            #region properties copy

            for (int i = 0; i &lt; advRow.Table.Columns.Count; i++)
            {
                if (!advRow.IsNull(advRow.Table.Columns[i]) &amp;&amp; !advRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(advRow.Table.Columns[i].ColumnName, advRow[i]);
                }
            }

            if (advRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(advRow["ID"]);
            }

            if (advRow.IsNull("BuyUnitID"))
            {
                ret.BuyUnit = null;
            }
            else
            {
                ret.BuyUnit = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["BuyUnitID"]), DicType.BuyUnitCinema);
            }

            if (advRow.IsNull("CityID"))
            {
                ret.City = null;
            }
            else
            {
                ret.City = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CityID"]), DicType.City);
            }

            if (advRow.IsNull("CommunicationTypeID"))
            {
                ret.CommunicationType = null;
            }
            else
            {
                ret.CommunicationType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CommunicationTypeID"]), DicType.CommunicationType);
            }

            if (advRow.IsNull("CurrencyID"))
            {
                ret.Currency = null;
            }
            else
            {
                ret.Currency = CommonController.CurrencyDictionaryItemGet(Convert.ToInt64(advRow["CurrencyID"]));
            }

            if (advRow.IsNull("DayOfWeekID"))
            {
                ret.DayOfWeekid = null;
            }
            else
            {
                ret.DayOfWeekid = Convert.ToInt64(advRow["DayOfWeekID"]);
            }

            if (advRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (advRow.IsNull("MediumID"))
            {
                ret.Medium = null;
            }
            else
            {
                ret.Medium = m_MediumController.MediumGet(Session, (Convert.ToInt64(advRow["MediumID"])));
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("SubjectGUID"))
            {
                ret.SubjectGUID = null;
            }
            else
            {
                ret.SubjectGUID = Convert.ToString(advRow["SubjectGUID"]);
            }

            if (advRow.IsNull("MediaplanOtherAgenciesID"))
            {
                ret.MediaplanOtherAgenciesid = null;
            }
            else
            {
                ret.MediaplanOtherAgenciesid = Convert.ToInt64(advRow["MediaplanOtherAgenciesID"]);
            }

            if (advRow.IsNull("PricelistSpecificationID"))
            {
                ret.PriceListSpecification = null;
            }
            else
            {
                ret.PriceListSpecification = Helper.Get&lt;PriceListAdvCinema&gt;(Session, Convert.ToInt64(advRow["PricelistSpecificationID"]));
            }

            if (advRow.IsNull("PriceListID"))
            {
                ret.PriceList = null;
            }
            else
            {
                ret.PriceList = Helper.Get&lt;PriceList&gt;(Session, Convert.ToInt64(advRow["PriceListID"]));
            }

            if (advRow.IsNull("MultikinoID"))
            {
                ret.Multikino = null;
            }
            else
            {
                ret.Multikino = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["MultikinoID"]), DicType.Multikino);
            }

            if (advRow.IsNull("TimeLimitsID"))
            {
                ret.TimeLimits = null;
            }
            else
            {
                ret.TimeLimits = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["TimeLimitsID"]), DicType.TimeConstraints);
            }




            if (advRow.IsNull("ReasonOfCancellationID"))
            {
                ret.ReasonOfCancellation = null;
            }
            else
            {
                ret.ReasonOfCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonOfCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("ReasonForOrderCancellationID"))
            {
                ret.ReasonForOrderCancellation = null;
            }
            else
            {
                ret.ReasonForOrderCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonForOrderCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("TradeTermsID"))
            {
                ret.TradeTerms = null;
            }
            else
            {
                ret.TradeTerms = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsID"])));
            }

            if (advRow.IsNull("TradeTermsImplementationID"))
            {
                ret.TradeTermsImplementation = null;
            }
            else
            {
                ret.TradeTermsImplementation = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsImplementationID"])));
            }




            #endregion

            return ret;
        }
        private MediaPlanAdvCinemaPostbuy GenerateAdvCinemaPostbuyObject(DataRow advRow, MediaPlan mediaPlan)
        {
            MediaPlanAdvCinemaPostbuy ret = new MediaPlanAdvCinemaPostbuy(mediaPlan.InstanceGUID);
            ret.MediaPlan = mediaPlan;
            #region properties copy

            for (int i = 0; i &lt; advRow.Table.Columns.Count; i++)
            {
                if (!advRow.IsNull(advRow.Table.Columns[i]) &amp;&amp; !advRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(advRow.Table.Columns[i].ColumnName, advRow[i]);
                }
            }

            if (advRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(advRow["ID"]);
            }

            if (advRow.IsNull("BuyUnitID"))
            {
                ret.BuyUnit = null;
            }
            else
            {
                ret.BuyUnit = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["BuyUnitID"]), DicType.BuyUnitCinema);
            }

            if (advRow.IsNull("CityID"))
            {
                ret.City = null;
            }
            else
            {
                ret.City = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CityID"]), DicType.City);
            }

            if (advRow.IsNull("CommunicationTypeID"))
            {
                ret.CommunicationType = null;
            }
            else
            {
                ret.CommunicationType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["CommunicationTypeID"]), DicType.CommunicationType);
            }

            if (advRow.IsNull("CurrencyID"))
            {
                ret.Currency = null;
            }
            else
            {
                ret.Currency = CommonController.CurrencyDictionaryItemGet(Convert.ToInt64(advRow["CurrencyID"]));
            }

            if (advRow.IsNull("DayOfWeekID"))
            {
                ret.DayOfWeekid = null;
            }
            else
            {
                ret.DayOfWeekid = Convert.ToInt64(advRow["DayOfWeekID"]);
            }

            if (advRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (advRow.IsNull("MediumID"))
            {
                ret.Medium = null;
            }
            else
            {
                ret.Medium = m_MediumController.MediumGet(Session, (Convert.ToInt64(advRow["MediumID"])));
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("MediahouseInstanceGUID"))
            {
                ret.MediahouseInstanceGUID = null;
            }
            else
            {
                ret.MediahouseInstanceGUID = Convert.ToString(advRow["MediahouseInstanceGUID"]);
            }

            if (advRow.IsNull("SubjectGUID"))
            {
                ret.SubjectGUID = null;
            }
            else
            {
                ret.SubjectGUID = Convert.ToString(advRow["SubjectGUID"]);
            }

            if (advRow.IsNull("MediaplanOtherAgenciesID"))
            {
                ret.MediaplanOtherAgenciesid = null;
            }
            else
            {
                ret.MediaplanOtherAgenciesid = Convert.ToInt64(advRow["MediaplanOtherAgenciesID"]);
            }

            if (advRow.IsNull("PricelistSpecificationID"))
            {
                ret.PriceListSpecification = null;
            }
            else
            {
                ret.PriceListSpecification = Helper.Get&lt;PriceListAdvCinema&gt;(Session, Convert.ToInt64(advRow["PricelistSpecificationID"]));
            }

            if (advRow.IsNull("PriceListID"))
            {
                ret.PriceList = null;
            }
            else
            {
                ret.PriceList = Helper.Get&lt;PriceList&gt;(Session, Convert.ToInt64(advRow["PriceListID"]));
            }

            if (advRow.IsNull("MultikinoID"))
            {
                ret.Multikino = null;
            }
            else
            {
                ret.Multikino = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["MultikinoID"]), DicType.Multikino);
            }

            if (advRow.IsNull("TimeLimitsID"))
            {
                ret.TimeLimits = null;
            }
            else
            {
                ret.TimeLimits = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["TimeLimitsID"]), DicType.TimeConstraints);
            }

            if (advRow.IsNull("PostbuyStateID"))
            {
                ret.PostbuyState = null;
            }
            else
            {
                ret.PostbuyState = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["PostbuyStateID"]), DicType.PostbuyState);
            }


            if (advRow.IsNull("ReasonOfCancellationID"))
            {
                ret.ReasonOfCancellation = null;
            }
            else
            {
                ret.ReasonOfCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonOfCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("ReasonForOrderCancellationID"))
            {
                ret.ReasonForOrderCancellation = null;
            }
            else
            {
                ret.ReasonForOrderCancellation = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(advRow["ReasonForOrderCancellationID"]), DicType.ReasonOfCancellation);
            }

            if (advRow.IsNull("TradeTermsID"))
            {
                ret.TradeTerms = null;
            }
            else
            {
                ret.TradeTerms = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsID"])));
            }

            if (advRow.IsNull("TradeTermsImplementationID"))
            {
                ret.TradeTermsImplementation = null;
            }
            else
            {
                ret.TradeTermsImplementation = m_TradeTermsController.TradeTermsGet(Session, (Convert.ToInt64(advRow["TradeTermsImplementationID"])));
            }

            if (advRow.IsNull("PostbuyNotes"))
            {
                ret.PostbuyNotes = null;
            }
            else
            {
                ret.PostbuyNotes = advRow["PostbuyNotes"].ToString();
            }
            ret.Themes = GenerateAdvCinemaPostbuyObject_GetThemes(ret.ID);

            #endregion

            return ret;
        }

        private Themes GenerateAdvCinemaPostbuyObject_GetThemes(long id)
        {
            Themes retThemes = null;
            StringBuilder sb = new StringBuilder();
            sb.Append(" SELECT t FROM Themes AS t ");
            sb.Append(" WHERE t.MediaPlanAdvCinemaID =:MediaPlanAdvCinemaID and t.IsDeleted=0 ");
            NHibernate.IQuery q = Session.CreateQuery(sb.ToString());
            q.SetParameter("MediaPlanAdvCinemaID", id);
            var ret = q.List&lt;Themes&gt;();
            if (ret != null &amp;&amp; ret.Count &gt; 0)
            { retThemes = ret.First(); }
            return retThemes;
        }

        private PricingEvent GeneratePricingEvent(PricingItem item, DataRow evRow, DataTable evTable)
        {
            PricingEvent ev = null;
            if (evRow != null)
            {
                ev = new PricingEvent(item.InstanceGUID);
                ev.ObjectGUID = item.ObjectGUID;

                ev.PricingItem = item;
                for (int i = 0; i &lt; evRow.Table.Columns.Count; i++)
                {
                    if (!evRow.IsNull(evRow.Table.Columns[i]) &amp;&amp; !evRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                    {
                        ev.SetValue(evRow.Table.Columns[i].ColumnName, evRow[i]);
                    }
                }

                if (evRow.IsNull("ID"))
                {
                    ev.ID = 0;
                }
                else
                {
                    ev.ID = Convert.ToInt64(evRow["ID"]);
                }

                if (evRow.IsNull("ObjectGUID"))
                {
                    ev.ObjectGUID = null;
                }
                else
                {
                    ev.ObjectGUID = Convert.ToString(evRow["ObjectGUID"]);
                }



                if (!evRow.IsNull("SelfGUID"))
                {
                    ev.SelfGUID = Convert.ToString(evRow["SelfGUID"]);
                }

                if (evRow.IsNull("PriceLevelID"))
                {
                    ev.PriceLevel = null;
                }
                else
                {
                    ev.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["PriceLevelID"]), DicType.PriceLevel);
                }

                if (evRow.IsNull("EventOriginID"))
                {
                    ev.EventOrigin = null;
                }
                else
                {
                    ev.EventOrigin = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventOriginID"]), DicType.EventOrigin);
                }

                if (evRow.IsNull("EventObjectTypeID"))
                {
                    ev.EventObjectType = null;
                }
                else
                {
                    ev.EventObjectType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventObjectTypeID"]), DicType.ObjectsStructureChild);
                }

                if (evRow.IsNull("EventTypeID"))
                {
                    ev.EventType = null;
                }
                else
                {
                    ev.EventType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventTypeID"]), DicType.EventType);
                }

                if (evRow.IsNull("EventPricingID"))
                {
                    ev.EventPricing = null;
                }
                else
                {
                    ev.EventPricing = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventPricingID"]), DicType.EventPricing);
                }

                if (evRow.IsNull("PriceListSurchargeID"))
                {
                    ev.PriceListSurcharge = null;
                }
                else
                {
                    ev.PriceListSurcharge = Helper.Get&lt;PriceListSurcharge&gt;(Session, Convert.ToInt64(evRow["PriceListSurchargeID"]));
                }

                if (evRow.IsNull("PriceListDiscountID"))
                {
                    ev.PriceListDiscount = null;
                }
                else
                {
                    ev.PriceListDiscount = Helper.Get&lt;PriceListDiscount&gt;(Session, Convert.ToInt64(evRow["PriceListDiscountID"]));
                }

                if (evRow.IsNull("TradeTermsSurchargeID"))
                {
                    ev.TradeTermsSurcharge = null;
                }
                else
                {
                    ev.TradeTermsSurcharge = Helper.Get&lt;TradeTermsSurcharge&gt;(Session, Convert.ToInt64(evRow["TradeTermsSurchargeID"]));
                }

                if (evRow.IsNull("TradeTermsDiscountID"))
                {
                    ev.TradeTermsDiscount = null;
                }
                else
                {
                    ev.TradeTermsDiscount = Helper.Get&lt;TradeTermsDiscount&gt;(Session, Convert.ToInt64(evRow["TradeTermsDiscountID"]));
                }

                if (evRow.IsNull("TradeTermsBonusID"))
                {
                    ev.TradeTermsBonus = null;
                }
                else
                {
                    ev.TradeTermsBonus = Helper.Get&lt;TradeTermsBonus&gt;(Session, Convert.ToInt64(evRow["TradeTermsBonusID"]));
                }

                if (evRow.IsNull("TradeTermsBonusID"))
                {
                    ev.TradeTermsBonus = null;
                }
                else
                {
                    ev.TradeTermsBonus = Helper.Get&lt;TradeTermsBonus&gt;(Session, Convert.ToInt64(evRow["TradeTermsBonusID"]));
                }

                if (evRow.IsNull("TradeTermsMediaFeeID"))
                {
                    ev.TradeTermsMediaFee = null;
                }
                else
                {
                    ev.TradeTermsMediaFee = Helper.Get&lt;TradeTermsMediaFee&gt;(Session, Convert.ToInt64(evRow["TradeTermsMediaFeeID"]));
                }

                if (evRow.IsNull("TradeTermsOtherFeeID"))
                {
                    ev.TradeTermsOtherFee = null;
                }
                else
                {
                    ev.TradeTermsOtherFee = Helper.Get&lt;TradeTermsOtherFee&gt;(Session, Convert.ToInt64(evRow["TradeTermsOtherFeeID"]));
                }
                if (evRow.IsNull("TradeTermsCommissionID"))
                {
                    ev.TradeTermsCommission = null;
                }
                else
                {
                    ev.TradeTermsCommission = Helper.Get&lt;TradeTermsSubjectTypeBrand&gt;(Session, Convert.ToInt64(evRow["TradeTermsCommissionID"]));
                }

                if (evRow.IsNull("PricingChimerySurchargeID"))
                {
                    ev.ChimerySurcharge = null;
                }
                else
                {
                    ev.ChimerySurcharge = Helper.Get&lt;PricingChimerySurcharge&gt;(Session, Convert.ToInt64(evRow["PricingChimerySurchargeID"]));
                }


                if (evRow.IsNull("PricingChimeryDiscountID"))
                {
                    ev.ChimeryDiscount = null;
                }
                else
                {
                    ev.ChimeryDiscount = Helper.Get&lt;PricingChimeryDiscount&gt;(Session, Convert.ToInt64(evRow["PricingChimeryDiscountID"]));
                }

                if (evRow.IsNull("CalculationBasisEventID"))
                {
                    ev.CalculationBasisEvent = null;
                }
                else
                {
                    DataRow[] e = evTable.Select("ID=" + evRow["CalculationBasisEventID"]);
                    if (e != null &amp;&amp; e.Count() &gt; 0)
                    {
                        ev.CalculationBasisEvent = GeneratePricingEvent(item, e[0], evTable);
                    }
                }

            }


            return ev;
        }

        private PricingEvent GeneratePricingEvent(PricingCompensationItem item, DataRow evRow, DataTable evTable)
        {
            PricingEvent ev = null;
            if (evRow != null)
            {
                ev = new PricingEvent(item.InstanceGUID);
                ev.ObjectGUID = item.ObjectGUID;
                ev.PricingCompensationItem = item;
                for (int i = 0; i &lt; evRow.Table.Columns.Count; i++)
                {
                    if (!evRow.IsNull(evRow.Table.Columns[i]) &amp;&amp; !evRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                    {
                        ev.SetValue(evRow.Table.Columns[i].ColumnName, evRow[i]);
                    }
                }

                if (evRow.IsNull("ID"))
                {
                    ev.ID = 0;
                }
                else
                {
                    ev.ID = Convert.ToInt64(evRow["ID"]);
                }

                if (evRow.IsNull("ObjectGUID"))
                {
                    ev.ObjectGUID = null;
                }
                else
                {
                    ev.ObjectGUID = Convert.ToString(evRow["ObjectGUID"]);
                }

                if (evRow.IsNull("PriceLevelID"))
                {
                    ev.PriceLevel = null;
                }
                else
                {
                    ev.PriceLevel = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["PriceLevelID"]), DicType.PriceLevel);
                }

                if (evRow.IsNull("EventOriginID"))
                {
                    ev.EventOrigin = null;
                }
                else
                {
                    ev.EventOrigin = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventOriginID"]), DicType.EventOrigin);
                }

                if (evRow.IsNull("EventObjectTypeID"))
                {
                    ev.EventObjectType = null;
                }
                else
                {
                    ev.EventObjectType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventObjectTypeID"]), DicType.ObjectsStructureChild);
                }

                if (evRow.IsNull("EventTypeID"))
                {
                    ev.EventType = null;
                }
                else
                {
                    ev.EventType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventTypeID"]), DicType.EventType);
                }

                if (evRow.IsNull("EventPricingID"))
                {
                    ev.EventPricing = null;
                }
                else
                {
                    ev.EventPricing = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(evRow["EventPricingID"]), DicType.EventPricing);
                }

                if (evRow.IsNull("PriceListSurchargeID"))
                {
                    ev.PriceListSurcharge = null;
                }
                else
                {
                    ev.PriceListSurcharge = Helper.Get&lt;PriceListSurcharge&gt;(Session, Convert.ToInt64(evRow["PriceListSurchargeID"]));
                }

                if (evRow.IsNull("PriceListDiscountID"))
                {
                    ev.PriceListDiscount = null;
                }
                else
                {
                    ev.PriceListDiscount = Helper.Get&lt;PriceListDiscount&gt;(Session, Convert.ToInt64(evRow["PriceListDiscountID"]));
                }

                if (evRow.IsNull("TradeTermsSurchargeID"))
                {
                    ev.TradeTermsSurcharge = null;
                }
                else
                {
                    ev.TradeTermsSurcharge = Helper.Get&lt;TradeTermsSurcharge&gt;(Session, Convert.ToInt64(evRow["TradeTermsSurchargeID"]));
                }

                if (evRow.IsNull("TradeTermsDiscountID"))
                {
                    ev.TradeTermsDiscount = null;
                }
                else
                {
                    ev.TradeTermsDiscount = Helper.Get&lt;TradeTermsDiscount&gt;(Session, Convert.ToInt64(evRow["TradeTermsDiscountID"]));
                }

                if (evRow.IsNull("TradeTermsBonusID"))
                {
                    ev.TradeTermsBonus = null;
                }
                else
                {
                    ev.TradeTermsBonus = Helper.Get&lt;TradeTermsBonus&gt;(Session, Convert.ToInt64(evRow["TradeTermsBonusID"]));
                }

                if (evRow.IsNull("TradeTermsBonusID"))
                {
                    ev.TradeTermsBonus = null;
                }
                else
                {
                    ev.TradeTermsBonus = Helper.Get&lt;TradeTermsBonus&gt;(Session, Convert.ToInt64(evRow["TradeTermsBonusID"]));
                }

                if (evRow.IsNull("TradeTermsMediaFeeID"))
                {
                    ev.TradeTermsMediaFee = null;
                }
                else
                {
                    ev.TradeTermsMediaFee = Helper.Get&lt;TradeTermsMediaFee&gt;(Session, Convert.ToInt64(evRow["TradeTermsMediaFeeID"]));
                }

                if (evRow.IsNull("TradeTermsOtherFeeID"))
                {
                    ev.TradeTermsOtherFee = null;
                }
                else
                {
                    ev.TradeTermsOtherFee = Helper.Get&lt;TradeTermsOtherFee&gt;(Session, Convert.ToInt64(evRow["TradeTermsOtherFeeID"]));
                }
                if (evRow.IsNull("TradeTermsCommissionID"))
                {
                    ev.TradeTermsCommission = null;
                }
                else
                {
                    ev.TradeTermsCommission = Helper.Get&lt;TradeTermsSubjectTypeBrand&gt;(Session, Convert.ToInt64(evRow["TradeTermsCommissionID"]));
                }

                if (evRow.IsNull("PricingChimerySurchargeID"))
                {
                    ev.ChimerySurcharge = null;
                }
                else
                {
                    ev.ChimerySurcharge = Helper.Get&lt;PricingChimerySurcharge&gt;(Session, Convert.ToInt64(evRow["PricingChimerySurchargeID"]));
                }


                if (evRow.IsNull("PricingChimeryDiscountID"))
                {
                    ev.ChimeryDiscount = null;
                }
                else
                {
                    ev.ChimeryDiscount = Helper.Get&lt;PricingChimeryDiscount&gt;(Session, Convert.ToInt64(evRow["PricingChimeryDiscountID"]));
                }

                if (evRow.IsNull("CalculationBasisEventID"))
                {
                    ev.CalculationBasisEvent = null;
                }
                else
                {
                    DataRow[] e = evTable.Select("ID=" + evRow["CalculationBasisEventID"]);
                    if (e != null &amp;&amp; e.Count() &gt; 0)
                    {
                        ev.CalculationBasisEvent = GeneratePricingEvent(item, e[0], evTable);
                    }
                }

            }


            return ev;
        }

        private PricingCompensationItem GenerateCompensationItem(PricingItem item, DataRow compItemRow)
        {
            PricingCompensationItem compItem = new PricingCompensationItem(item.InstanceGUID);
            compItem.ObjectGUID = item.ObjectGUID;
            compItem.PricingItem = item;

            for (int i = 0; i &lt; compItemRow.Table.Columns.Count; i++)
            {
                if (!compItemRow.IsNull(compItemRow.Table.Columns[i]) &amp;&amp; !compItemRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    compItem.SetValue(compItemRow.Table.Columns[i].ColumnName, compItemRow[i]);
                }
            }

            if (compItemRow.IsNull("ID"))
            {
                compItem.ID = 0;
            }
            else
            {
                compItem.ID = Convert.ToInt64(compItemRow["ID"]);
            }

            if (compItemRow.IsNull("ObjectGUID"))
            {
                compItem.ObjectGUID = null;
            }
            else
            {
                compItem.ObjectGUID = Convert.ToString(compItemRow["ObjectGUID"]);
            }

            if (compItemRow.IsNull("OriginID"))
            {
                compItem.Origin = null;
            }
            else
            {
                compItem.Origin = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(compItemRow["OriginID"]), DicType.CompensationRowOrigin);
            }

            if (compItemRow.IsNull("CategoryID"))
            {
                compItem.Category = null;
            }
            else
            {
                compItem.Category = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(compItemRow["CategoryID"]), DicType.CompensationRowCategory);
            }
            compItem = new PricingCompensationItem(item.InstanceGUID);
            compItem.PricingItem = item;
            compItem.ObjectGUID = item.ObjectGUID;
            for (int i = 0; i &lt; compItemRow.Table.Columns.Count; i++)
            {
                if (!compItemRow.IsNull(compItemRow.Table.Columns[i]) &amp;&amp; !compItemRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    compItem.SetValue(compItemRow.Table.Columns[i].ColumnName, compItemRow[i]);
                }
            }

            if (compItemRow.IsNull("ID"))
            {
                compItem.ID = 0;
            }
            else
            {
                compItem.ID = Convert.ToInt64(compItemRow["ID"]);
            }

            if (compItemRow.IsNull("OriginID"))
            {
                compItem.Origin = null;
            }
            else
            {
                compItem.Origin = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(compItemRow["OriginID"]), DicType.CompensationRowOrigin);
            }

            if (compItemRow.IsNull("CategoryID"))
            {
                compItem.Category = null;
            }
            else
            {
                compItem.Category = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(compItemRow["CategoryID"]), DicType.CompensationRowCategory);
            }

            return compItem;

        }

        private PricingItem GeneratePricingItem(DataRow pricingRow, DataTable compItemTab, DataTable eventTable, MediaPlanAdvCinema mediaPlanAdv)
        {
            PricingItem ret = new PricingItem(mediaPlanAdv.InstanceGUID);
            ret.MediaPlanAdvCinema = mediaPlanAdv;
            #region properties copy

            for (int i = 0; i &lt; pricingRow.Table.Columns.Count; i++)
            {
                if (!pricingRow.IsNull(pricingRow.Table.Columns[i]) &amp;&amp; !pricingRow.Table.Columns[i].ColumnName.EndsWith("ID"))
                {
                    ret.SetValue(pricingRow.Table.Columns[i].ColumnName, pricingRow[i]);
                }
            }

            if (pricingRow.IsNull("ID"))
            {
                ret.ID = 0;
            }
            else
            {
                ret.ID = Convert.ToInt64(pricingRow["ID"]);
            }

            if (pricingRow.IsNull("ObjectGUID"))
            {
                ret.ObjectGUID = null;
            }
            else
            {
                ret.ObjectGUID = Convert.ToString(pricingRow["ObjectGUID"]);
            }

            if (pricingRow.IsNull("PriceTypeID"))
            {
                ret.PriceType = null;
            }
            else
            {
                ret.PriceType = CommonController.GetDicItem&lt;DictionaryItem&gt;(Convert.ToInt64(pricingRow["PriceTypeID"]), DicType.SecondPrizePricing);
            }

            if (compItemTab != null &amp;&amp; compItemTab.Rows.Count &gt; 0)
            {
                DataRow[] compRows = compItemTab.Select("PricingItemID=" + ret.ID.ToString());
                for (int j = 0; j &lt; compRows.Count(); j++)
                {
                    PricingCompensationItem item = GenerateCompensationItem(ret, compRows[j]);
                    if (eventTable != null &amp;&amp; eventTable.Rows.Count &gt; 0)
                    {
                        DataRow[] evRows = eventTable.Select("PricingCompensationItemID=" + item.ID.ToString());
                        for (int k = 0; k &lt; evRows.Count(); k++)
                        {
                            PricingEvent ev = GeneratePricingEvent(item, evRows[k], eventTable);
                            if (item.PricingEventList == null)
                            {
                                item.PricingEventList = item.PricingEventList.CreateNewObservableCollection();
                            }
                            item.PricingEventList.Add(ev);
                        }
                    }
                    if (ret.PricingCompensationItemList == null)
                    {
                        ret.PricingCompensationItemList = ret.PricingCompensationItemList.CreateNewObservableCollection();
                    }
                    ret.PricingCompensationItemList.Add(item);
                }
            }

            if (eventTable != null &amp;&amp; eventTable.Rows.Count &gt; 0)
            {
                DataRow[] evRows = eventTable.Select("PricingItemID=" + ret.ID.ToString());
                for (int j = 0; j &lt; evRows.Count(); j++)
                {
                    PricingEvent ev = GeneratePricingEvent(ret, evRows[j], eventTable);
                    if (ret.PricingEventList == null)
                    {
                        ret.PricingEventList = ret.PricingEventList.CreateNewObservableCollection();
                    }
                    ret.PricingEventList.Add(ev);
                }
            }

            return ret;


            #endregion
        }


        public void FillAdvCinemaPricing(IList&lt;MediaPlanAdvCinema&gt; advs)
        {
            DataSet ds = new DataSet();
            DataTable tab = new DataTable("_MediaPlanAdvIDs");
            tab.Columns.Add("ID", Type.GetType("System.Int64"));
            for (int i = 0; i &lt; advs.Count; i++)
            {
                DataRow row = tab.NewRow();
                row["ID"] = advs[i].ID;
                tab.Rows.Add(row);
            }
            string connString = CommonController.AuthenticationInfo.ConnectionStrings[GlobalVariables.OMG_DATABASE];
            SqlConnection sql = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand("dbo.PricingItemGetAdvCinema", sql);
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlParameter sp = cmd.Parameters.AddWithValue("@pMediaPlanAdvCinemaID", tab);
            sp.SqlDbType = SqlDbType.Structured;
            sql.Open();
            da.Fill(ds);
            sql.Close();

            if (ds.Tables.Count &gt; 0)
            {
                for (int i = 0; i &lt; ds.Tables[0].Rows.Count; i++)
                {
                    var ad = from a in advs where a.ID == Convert.ToInt64(ds.Tables[0].Rows[i]["MediaPlanAdvCinemaID"]) select a;

                    if (ad.Count() &gt; 0)
                    {
                        MediaPlanAdvCinema adv = ad.First();
                        PricingItem item = GeneratePricingItem(ds.Tables[0].Rows[i], ds.Tables[1], ds.Tables[2], adv);
                        if (adv.PricingItemList == null)
                            adv.PricingItemList = adv.PricingItemList.CreateNewObservableCollection();
                        adv.PricingItemList.Add(item);
                    }
                }

            }


        }

        public void FillMediaPlanAdvCinema(MediaPlan mediaPlan)
        {
            DataSet ds = new DataSet();
            string connString = CommonController.AuthenticationInfo.ConnectionStrings[GlobalVariables.OMG_DATABASE];
            SqlConnection sql = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand("dbo.MediaPlanAdvCinemaGet", sql);
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlParameter sp = cmd.Parameters.AddWithValue("@pMediaPlanID", mediaPlan.ID);
            sp.SqlDbType = SqlDbType.BigInt;
            sql.Open();
            da.Fill(ds);
            sql.Close();

            if (ds.Tables.Count &gt; 0)
            {

                if (ds.Tables[0].Rows.Count &gt; 0 &amp;&amp; mediaPlan.MediaPlanAdvCinemaPriceListList == null)
                    mediaPlan.MediaPlanAdvCinemaPriceListList = mediaPlan.MediaPlanAdvCinemaPriceListList.CreateNewObservableCollection();
                if (ds.Tables[1].Rows.Count &gt; 0 &amp;&amp; mediaPlan.MediaPlanAdvCinemaShoppingList == null)
                    mediaPlan.MediaPlanAdvCinemaShoppingList = mediaPlan.MediaPlanAdvCinemaShoppingList.CreateNewObservableCollection();
                if (ds.Tables[2].Rows.Count &gt; 0 &amp;&amp; mediaPlan.MediaPlanAdvCinemaClientList == null)
                    mediaPlan.MediaPlanAdvCinemaClientList = mediaPlan.MediaPlanAdvCinemaClientList.CreateNewObservableCollection();
                if (ds.Tables[3].Rows.Count &gt; 0 &amp;&amp; mediaPlan.MediaPlanAdvCinemaChimeryList == null)
                    mediaPlan.MediaPlanAdvCinemaChimeryList = mediaPlan.MediaPlanAdvCinemaChimeryList.CreateNewObservableCollection();
                if (ds.Tables[4].Rows.Count &gt; 0 &amp;&amp; mediaPlan.MediaPlanAdvCinemaPostbuyList == null)
                    mediaPlan.MediaPlanAdvCinemaPostbuyList = mediaPlan.MediaPlanAdvCinemaPostbuyList.CreateNewObservableCollection();

                for (int i = 0; i &lt; ds.Tables[0].Rows.Count; i++)
                {
                    mediaPlan.MediaPlanAdvCinemaPriceListList.Add(GenerateAdvCinemaPriceListObject(ds.Tables[0].Rows[i], mediaPlan));
                }

                for (int i = 0; i &lt; ds.Tables[1].Rows.Count; i++)
                {
                    mediaPlan.MediaPlanAdvCinemaShoppingList.Add(GenerateAdvCinemaShoppingObject(ds.Tables[1].Rows[i], mediaPlan));
                }

                for (int i = 0; i &lt; ds.Tables[2].Rows.Count; i++)
                {
                    mediaPlan.MediaPlanAdvCinemaClientList.Add(GenerateAdvCinemaClientObject(ds.Tables[2].Rows[i], mediaPlan));
                }

                for (int i = 0; i &lt; ds.Tables[3].Rows.Count; i++)
                {
                    mediaPlan.MediaPlanAdvCinemaChimeryList.Add(GenerateAdvCinemaChimeryObject(ds.Tables[3].Rows[i], mediaPlan));
                }

                for (int i = 0; i &lt; ds.Tables[4].Rows.Count; i++)
                {
                    mediaPlan.MediaPlanAdvCinemaPostbuyList.Add(GenerateAdvCinemaPostbuyObject(ds.Tables[4].Rows[i], mediaPlan));
                }

            }
        }

        #endregion

        public void MediaPlanAdvCinemaUpdate(MediaPlan mp, int setNumber, bool IsGrouping)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            List&lt;MediaPlanAdvCinema&gt; advList = new List&lt;MediaPlanAdvCinema&gt;();
            DataTable dt = GetDT_MediaPlanAdvCinemaType();
            advList = GetListOfMediaPlanAdvCinema(mp, setNumber, IsGrouping);
            FilDT_MediaPlanAdvCinemaType(advList, dt);
            ;

            string connString = CommonController.AuthenticationInfo.ConnectionStrings[GlobalVariables.OMG_DATABASE];
            System.Data.SqlClient.SqlConnection sql = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("dbo.MediaPlanAdvCinemaUpdate", sql);
            cmd.CommandType = CommandType.StoredProcedure;
            System.Data.SqlClient.SqlParameter sp = cmd.Parameters.AddWithValue("@TableVariable", dt);
            sp.SqlDbType = SqlDbType.Structured;
            sql.Open();
            cmd.ExecuteNonQuery();
            sql.Close();

            sw.Stop();
            ;
        }

        public void MediaPlanAdvCinemaInsert(MediaPlan mp, List&lt;int&gt; CurrentSetNumberList)
        {
            List&lt;MediaPlanAdvCinema&gt; advList = GetListOfMediaPlanAdvCinema(mp, CurrentSetNumberList, false);
            DataTable dt = GetDT_MediaPlanAdvCinemaType();
            FilDT_MediaPlanAdvCinemaType(advList, dt);

            string connString = CommonController.AuthenticationInfo.ConnectionStrings[GlobalVariables.OMG_DATABASE];
            System.Data.SqlClient.SqlConnection sql = new System.Data.SqlClient.SqlConnection(connString);
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("dbo.MediaPlanAdvCinemaInsert", sql);
            cmd.CommandType = CommandType.StoredProcedure;
            System.Data.SqlClient.SqlParameter sp = cmd.Parameters.AddWithValue("@TableVariable", dt);
            DataSet ds = new DataSet();
            sp.SqlDbType = SqlDbType.Structured;
            System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmd);
            sql.Open();
            da.Fill(ds);
            sql.Close();

            if (ds != null &amp;&amp; ds.Tables != null &amp;&amp; ds.Tables.Count &gt; 0)
            {
                var d = ds.Tables[0].AsEnumerable();
                advList.ForEach(a =&gt;
                {
                    var id = d.Where(dr =&gt; dr.Field&lt;string&gt;(1) == a.MPAdvGUID).Select(dr =&gt; dr.Field&lt;long&gt;(0));
                    if (id != null &amp;&amp; id.Count() &gt; 0)
                    {
                        var i = id.First();
                        a.ID = id.First();
                    }
                });
            }
        }

        public List&lt;MediaPlanAdvCinema&gt; GetListOfMediaPlanAdvCinema(MediaPlan mp, int setNumber, bool IsGrouping)
        { return GetListOfMediaPlanAdvCinema(mp, new List&lt;int&gt;() { setNumber }, IsGrouping); }
        public List&lt;MediaPlanAdvCinema&gt; GetListOfMediaPlanAdvCinema(MediaPlan mp, List&lt;int&gt; setNumberList, bool IsGrouping)
        {
            List&lt;MediaPlanAdvCinema&gt; advList = new List&lt;MediaPlanAdvCinema&gt;();

            if (IsGrouping)
            {
                if (IsGrouping &amp;&amp; mp.MediaPlanCinemaGroupedWrapper != null)
                {
                    if (setNumberList != null &amp;&amp; setNumberList.Count &gt; 0)
                    {
                        int setNumber = setNumberList[0];
                        var ch = mp.MediaPlanCinemaGroupedWrapper.MediaPlanAdvCinemaGroupedChimeryList.Where(w =&gt; (w as IMediaPlanAdvCinemaGrouped).SetNumberGrouped == setNumber);
                        if (ch != null &amp;&amp; ch.Count() &gt; 0)
                        {
                            advList = advList.Concat((ch.First() as IMediaPlanAdvCinemaGrouped).MediaPlanAdvCinemaList).ToList();
                        }
                        var cl = mp.MediaPlanCinemaGroupedWrapper.MediaPlanAdvCinemaGroupedClientList.Where(w =&gt; (w as IMediaPlanAdvCinemaGrouped).SetNumberGrouped == setNumber);
                        if (cl != null &amp;&amp; cl.Count() &gt; 0)
                        {
                            advList = advList.Concat((cl.First() as IMediaPlanAdvCinemaGrouped).MediaPlanAdvCinemaList).ToList();
                        }
                        var po = mp.MediaPlanCinemaGroupedWrapper.MediaPlanAdvCinemaGroupedPostbuyList.Where(w =&gt; (w as IMediaPlanAdvCinemaGrouped).SetNumberGrouped == setNumber);
                        if (po != null &amp;&amp; po.Count() &gt; 0)
                        {
                            advList = advList.Concat((po.First() as IMediaPlanAdvCinemaGrouped).MediaPlanAdvCinemaList).ToList();
                        }
                        var pr = mp.MediaPlanCinemaGroupedWrapper.MediaPlanAdvCinemaGroupedPriceListList.Where(w =&gt; (w as IMediaPlanAdvCinemaGrouped).SetNumberGrouped == setNumber);
                        if (pr != null &amp;&amp; pr.Count() &gt; 0)
                        {
                            advList = advList.Concat((pr.First() as IMediaPlanAdvCinemaGrouped).MediaPlanAdvCinemaList).ToList();
                        }
                        var sh = mp.MediaPlanCinemaGroupedWrapper.MediaPlanAdvCinemaGroupedShoppingList.Where(w =&gt; (w as IMediaPlanAdvCinemaGrouped).SetNumberGrouped == setNumber);
                        if (sh != null &amp;&amp; sh.Count() &gt; 0)
                        {
                            advList = advList.Concat((sh.First() as IMediaPlanAdvCinemaGrouped).MediaPlanAdvCinemaList).ToList();
                        }
                    }
                }
            }
            else
            {
                MediaPlanAdvCinemaChimery advChimery;
                MediaPlanAdvCinemaClient advClient;
                MediaPlanAdvCinemaPostbuy advPostbuy;
                MediaPlanAdvCinemaPriceList advPriceList;
                MediaPlanAdvCinemaShopping advShopping;
                foreach (int setNumber in setNumberList)
                {
                    GetMediaPlanAdvCinemaCurrentSet(mp, setNumber, out advChimery, out advClient, out advPostbuy, out advPriceList, out advShopping);
                    advList.Add(advChimery as MediaPlanAdvCinema);
                    advList.Add(advClient as MediaPlanAdvCinema);
                    advList.Add(advPostbuy as MediaPlanAdvCinema);
                    advList.Add(advPriceList as MediaPlanAdvCinema);
                    advList.Add(advShopping as MediaPlanAdvCinema);
                }
            }
            return advList;
        }


        private void FilDT_MediaPlanAdvCinemaType(List&lt;MediaPlanAdvCinema&gt; advList, DataTable dt)
        {
            if (advList != null &amp;&amp; advList.Count &gt; 0)
            {
                advList.ToList().ForEach(a =&gt;
                {
                    DataRow dr = dt.NewRow();
                    dr["ID"] = a.ID;
                    dr["MediaPlanID"] = a.MediaPlan != null ? a.MediaPlan.ID : Convert.DBNull;
                    dr["PriceTypeID"] = a.PriceType != null ? a.PriceType.ID : Convert.DBNull;
                    dr["PriceTypeCode"] = a.PriceTypeCode != null ? a.PriceTypeCode : Convert.DBNull;
                    dr["MediumID"] = a.Medium != null ? a.Medium.ID : Convert.DBNull;
                    dr["MediahouseInstanceGUID"] = a.MediahouseInstanceGUID != null ? a.MediahouseInstanceGUID : Convert.DBNull;
                    dr["PriceListID"] = a.PriceList != null ? a.PriceList.ID : Convert.DBNull;
                    dr["SubjectGUID"] = a.SubjectGUID != null ? a.SubjectGUID : Convert.DBNull;
                    dr["MediaplanOtherAgenciesID"] = a.MediaplanOtherAgenciesid != null ? a.MediaplanOtherAgenciesid != null : Convert.DBNull;
                    dr["PricelistSpecificationID"] = a.PriceListSpecification != null ? a.PriceListSpecification.ID : Convert.DBNull;
                    dr["CurrencyID"] = a.Currency != null ? a.Currency.ID : Convert.DBNull;
                    dr["ExchangeRate"] = a.ExchangeRate != null ? a.ExchangeRate : Convert.DBNull;
                    if (a is MediaPlanAdvCinemaShopping)
                    {
                        dr["IsInvoice"] = (a as MediaPlanAdvCinemaShopping).IsInvoice != null ? (a as MediaPlanAdvCinemaShopping).IsInvoice : Convert.DBNull;
                        dr["IsBonus"] = (a as MediaPlanAdvCinemaShopping).IsBonus != null ? (a as MediaPlanAdvCinemaShopping).IsBonus : Convert.DBNull;
                        dr["IsForBonus"] = (a as MediaPlanAdvCinemaShopping).IsForBonus != null ? (a as MediaPlanAdvCinemaShopping).IsForBonus : Convert.DBNull;
                        dr["IsFree"] = (a as MediaPlanAdvCinemaShopping).IsFree != null ? (a as MediaPlanAdvCinemaShopping).IsFree : Convert.DBNull;
                        dr["IsBonusFree"] = (a as MediaPlanAdvCinemaShopping).IsBonusFree != null ? (a as MediaPlanAdvCinemaShopping).IsBonusFree : Convert.DBNull;
                        dr["FreeTypeID"] = (a as MediaPlanAdvCinemaShopping).FreeType != null ? (a as MediaPlanAdvCinemaShopping).FreeType.ID : Convert.DBNull;
                        dr["PercentFree"] = (a as MediaPlanAdvCinemaShopping).PercentFree != null ? (a as MediaPlanAdvCinemaShopping).PercentFree : Convert.DBNull;
                        dr["FreeVolume"] = (a as MediaPlanAdvCinemaShopping).FreeVolume != null ? (a as MediaPlanAdvCinemaShopping).FreeVolume : Convert.DBNull;
                        dr["PriceLevelID"] = (a as MediaPlanAdvCinemaShopping).PriceLevel != null ? (a as MediaPlanAdvCinemaShopping).PriceLevel.ID : Convert.DBNull;
                    }
                    if (a is MediaPlanAdvCinemaClient)
                    {
                        dr["IsInvoice"] = (a as MediaPlanAdvCinemaClient).IsInvoice != null ? (a as MediaPlanAdvCinemaClient).IsInvoice : Convert.DBNull;
                        dr["IsBonus"] = (a as MediaPlanAdvCinemaClient).IsBonus != null ? (a as MediaPlanAdvCinemaClient).IsBonus : Convert.DBNull;
                        dr["IsForBonus"] = (a as MediaPlanAdvCinemaClient).IsForBonus != null ? (a as MediaPlanAdvCinemaClient).IsForBonus : Convert.DBNull;
                        dr["IsFree"] = (a as MediaPlanAdvCinemaClient).IsFree != null ? (a as MediaPlanAdvCinemaClient).IsFree : Convert.DBNull;
                        //dr["IsBonusFree"] = (a as MediaPlanAdvCinemaClient).IsBonusFree;
                        dr["FreeTypeID"] = (a as MediaPlanAdvCinemaClient).FreeType != null ? (a as MediaPlanAdvCinemaClient).FreeType.ID : Convert.DBNull;
                        dr["PercentFree"] = (a as MediaPlanAdvCinemaClient).PercentFree != null ? (a as MediaPlanAdvCinemaClient).PercentFree : Convert.DBNull;
                        dr["FreeVolume"] = (a as MediaPlanAdvCinemaClient).FreeVolume != null ? (a as MediaPlanAdvCinemaClient).FreeVolume : Convert.DBNull;
                        dr["PriceLevelID"] = (a as MediaPlanAdvCinemaClient).PriceLevel != null ? (a as MediaPlanAdvCinemaClient).PriceLevel.ID : Convert.DBNull;
                    }
                    dr["IsUnusual"] = a.IsUnusual != null ? a.IsUnusual : Convert.DBNull;
                    dr["IsProductionCost"] = a.IsProductionCost != null ? a.IsProductionCost : Convert.DBNull;
                    dr["Motive"] = a.Motive != null ? a.Motive : Convert.DBNull;
                    dr["DeadlineDate"] = a.DeadlineDate != null ? a.DeadlineDate : Convert.DBNull;
                    dr["CityID"] = a.City != null ? a.City.ID : Convert.DBNull;
                    dr["MultikinoID"] = a.Multikino != null ? a.Multikino.ID : Convert.DBNull;
                    dr["UnitPrice"] = a.UnitPrice != null ? a.UnitPrice : Convert.DBNull;
                    dr["Attendance"] = a.Attendance != null ? a.Attendance : Convert.DBNull;
                    dr["TimeLimitsID"] = a.TimeLimits != null ? a.TimeLimits.ID : Convert.DBNull;
                    dr["BuyUnitID"] = a.BuyUnit != null ? a.BuyUnit.ID : Convert.DBNull;
                    dr["NoOfUnits"] = a.NoOfUnits != null ? a.NoOfUnits : Convert.DBNull;
                    dr["Price"] = a.Price != null ? a.Price : Convert.DBNull;
                    dr["Description"] = a.Description != null ? a.Description : Convert.DBNull;
                    dr["CommunicationTypeID"] = a.CommunicationType != null ? a.CommunicationType.ID : Convert.DBNull;
                    dr["MO"] = a.Mo != null ? a.Mo : Convert.DBNull;
                    dr["TU"] = a.Tu != null ? a.Tu : Convert.DBNull;
                    dr["WED"] = a.Wed != null ? a.Wed : Convert.DBNull;
                    dr["THR"] = a.Thr != null ? a.Thr : Convert.DBNull;
                    dr["FR"] = a.Fr != null ? a.Fr : Convert.DBNull;
                    dr["SA"] = a.Sa != null ? a.Sa : Convert.DBNull;
                    dr["SU"] = a.Su != null ? a.Su : Convert.DBNull;
                    dr["SpotLength"] = a.SpotLength != null ? a.SpotLength : Convert.DBNull;
                    dr["Length"] = a.Length != null ? a.Length : Convert.DBNull;
                    dr["Notes"] = a.Notes != null ? a.Notes : Convert.DBNull;
                    dr["MustBook"] = a.MustBook != null ? a.MustBook : Convert.DBNull;
                    dr["DateFrom"] = a.DateFrom != null ? a.DateFrom : Convert.DBNull;
                    dr["DateTo"] = a.DateTo != null ? a.DateTo : Convert.DBNull;
                    dr["DayOfWeekID"] = a.DayOfWeekid != null ? a.DayOfWeekid : Convert.DBNull;
                    dr["MediumNetID"] = a.MediumNetid != null ? a.MediumNetid : Convert.DBNull;
                    dr["NetworkCompositionText"] = a.NetworkCompositionText != null ? a.NetworkCompositionText : Convert.DBNull;
                    dr["MainAdvID"] = a.MainAdvid != null ? a.MainAdvid : Convert.DBNull;
                    dr["CancelReservation"] = a.CancelReservation != null ? a.CancelReservation : Convert.DBNull;
                    dr["ReasonOfCancellationID"] = a.ReasonOfCancellation != null ? a.ReasonOfCancellation.ID : Convert.DBNull;
                    dr["OrderCancelation"] = a.OrderCancelation != null ? a.OrderCancelation : Convert.DBNull;
                    dr["ReasonForOrderCancellationID"] = a.ReasonForOrderCancellation != null ? a.ReasonForOrderCancellation.ID : Convert.DBNull;
                    dr["SetNumber"] = a.SetNumber != null ? a.SetNumber : Convert.DBNull;
                    dr["InstanceGUID"] = a.InstanceGUID != null ? a.InstanceGUID : Convert.DBNull;
                    dr["CreatedBy"] = a.CreatedBy != null ? a.CreatedBy : Convert.DBNull;
                    dr["CreateDate"] = a.CreateDate != null ? a.CreateDate : Convert.DBNull;
                    dr["LastChangeDate"] = a.LastChangeDate != null ? a.LastChangeDate : Convert.DBNull;
                    dr["LastChangeBy"] = a.LastChangeBy != null ? a.LastChangeBy : Convert.DBNull;
                    dr["IsDeleted"] = a.IsDeleted != null ? a.IsDeleted : Convert.DBNull;
                    dr["TradeTermsID"] = a.TradeTerms != null ? a.TradeTerms.ID : Convert.DBNull;
                    if (a is MediaPlanAdvCinemaPostbuy)
                    {
                        if ((a as MediaPlanAdvCinemaPostbuy).PostbuyState != null)
                        {
                            dr["PostbuyStateID"] = (a as MediaPlanAdvCinemaPostbuy).PostbuyState.ID;
                        }
                        dr["PostbuyNotes"] = (a as MediaPlanAdvCinemaPostbuy).PostbuyNotes != null ? (a as MediaPlanAdvCinemaPostbuy).PostbuyNotes : Convert.DBNull;
                    }
                    dr["TradeTermsImplementationID"] = a.TradeTermsImplementation != null ? a.TradeTermsImplementation.ID : Convert.DBNull;
                    dr["Mediahouse_Description"] = a.Mediahouse_Description != null ? a.Mediahouse_Description : Convert.DBNull;
                    dr["Subject_Description"] = a.Subject_Description != null ? a.Subject_Description : Convert.DBNull;
                    dr["MPAdvGUID"] = a.MPAdvGUID != null ? a.MPAdvGUID : Convert.DBNull;

                    dr["GGC1"] = a.GGC1 != null ? a.GGC1 : Convert.DBNull;
                    dr["GC1"] = a.GC1 != null ? a.GC1 : Convert.DBNull;
                    dr["MNC1"] = a.MNC1 != null ? a.MNC1 : Convert.DBNull;
                    dr["MNNC1"] = a.MNNC1 != null ? a.MNNC1 : Convert.DBNull;
                    dr["CN1"] = a.CN1 != null ? a.CN1 : Convert.DBNull;
                    dr["CNN1"] = a.CNN1 != null ? a.CNN1 : Convert.DBNull;
                    dr["GGC2"] = a.GGC2 != null ? a.GGC2 : Convert.DBNull;
                    dr["GC2"] = a.GC2 != null ? a.GC2 : Convert.DBNull;
                    dr["MNC2"] = a.MNC2 != null ? a.MNC2 : Convert.DBNull;
                    dr["MNNC2"] = a.MNNC2 != null ? a.MNNC2 : Convert.DBNull;
                    dr["CN2"] = a.CN2 != null ? a.CN2 : Convert.DBNull;
                    dr["CNN2"] = a.CNN2 != null ? a.CNN2 : Convert.DBNull;

                    dt.Rows.Add(dr);
                }
                    );
            }
        }
        private DataTable GetDT_MediaPlanAdvCinemaType()
        {
            DataTable dt = new DataTable("MediaPlanAdvCinemaType");

            dt.Columns.Add("ID", typeof(long));
            dt.Columns.Add("MediaPlanID", typeof(long));
            dt.Columns.Add("PriceTypeID", typeof(long));
            dt.Columns.Add("PriceTypeCode");
            dt.Columns.Add("MediumID", typeof(long));
            dt.Columns.Add("MediahouseInstanceGUID");
            dt.Columns.Add("PriceListID", typeof(long));
            dt.Columns.Add("SubjectGUID");
            dt.Columns.Add("MediaplanOtherAgenciesID", typeof(long));
            dt.Columns.Add("PricelistSpecificationID", typeof(long));
            dt.Columns.Add("CurrencyID", typeof(long));
            dt.Columns.Add("ExchangeRate", typeof(decimal));
            dt.Columns.Add("IsInvoice");
            dt.Columns.Add("IsUnusual");
            dt.Columns.Add("IsProductionCost");
            dt.Columns.Add("IsBonus");
            dt.Columns.Add("IsForBonus");
            dt.Columns.Add("Motive");
            dt.Columns.Add("IsFree");
            dt.Columns.Add("IsBonusFree");
            dt.Columns.Add("FreeTypeID");
            dt.Columns.Add("PercentFree", typeof(decimal));
            dt.Columns.Add("FreeVolume", typeof(decimal));
            dt.Columns.Add("PriceLevelID", typeof(long));
            dt.Columns.Add("DeadlineDate");
            dt.Columns.Add("CityID", typeof(long));
            dt.Columns.Add("MultikinoID", typeof(long));
            dt.Columns.Add("UnitPrice", typeof(decimal));
            dt.Columns.Add("Attendance", typeof(int));
            dt.Columns.Add("TimeLimitsID", typeof(long));
            dt.Columns.Add("BuyUnitID", typeof(long));
            dt.Columns.Add("NoOfUnits", typeof(int));
            dt.Columns.Add("Price", typeof(decimal));
            dt.Columns.Add("Description");
            dt.Columns.Add("CommunicationTypeID", typeof(long));
            dt.Columns.Add("MO");
            dt.Columns.Add("TU");
            dt.Columns.Add("WED");
            dt.Columns.Add("THR");
            dt.Columns.Add("FR");
            dt.Columns.Add("SA");
            dt.Columns.Add("SU");
            dt.Columns.Add("SpotLength", typeof(int));
            dt.Columns.Add("Length", typeof(long));
            dt.Columns.Add("Notes");
            dt.Columns.Add("MustBook");
            dt.Columns.Add("DateFrom", typeof(DateTime));
            dt.Columns.Add("DateTo", typeof(DateTime));
            dt.Columns.Add("DayOfWeekID", typeof(long));
            dt.Columns.Add("MediumNetID", typeof(long));
            dt.Columns.Add("NetworkCompositionText");
            dt.Columns.Add("MainAdvID", typeof(long));
            dt.Columns.Add("CancelReservation");
            dt.Columns.Add("ReasonOfCancellationID", typeof(long));
            dt.Columns.Add("OrderCancelation");
            dt.Columns.Add("ReasonForOrderCancellationID", typeof(long));
            dt.Columns.Add("SetNumber", typeof(int));
            dt.Columns.Add("InstanceGUID");
            dt.Columns.Add("CreatedBy");
            dt.Columns.Add("CreateDate", typeof(DateTime));
            dt.Columns.Add("LastChangeDate", typeof(DateTime));
            dt.Columns.Add("LastChangeBy");
            dt.Columns.Add("IsDeleted");
            dt.Columns.Add("TradeTermsID", typeof(long));
            dt.Columns.Add("PostbuyStateID", typeof(long));
            dt.Columns.Add("PostbuyNotes");
            dt.Columns.Add("TradeTermsImplementationID", typeof(long));
            dt.Columns.Add("Mediahouse_Description");
            dt.Columns.Add("Subject_Description");
            dt.Columns.Add("MPAdvGUID");

            dt.Columns.Add("GGC1", typeof(decimal));
            dt.Columns.Add("GC1", typeof(decimal));
            dt.Columns.Add("MNC1", typeof(decimal));
            dt.Columns.Add("MNNC1", typeof(decimal));
            dt.Columns.Add("CN1", typeof(decimal));
            dt.Columns.Add("CNN1", typeof(decimal));
            dt.Columns.Add("GGC2", typeof(decimal));
            dt.Columns.Add("GC2", typeof(decimal));
            dt.Columns.Add("MNC2", typeof(decimal));
            dt.Columns.Add("MNNC2", typeof(decimal));
            dt.Columns.Add("CN2", typeof(decimal));
            dt.Columns.Add("CNN2", typeof(decimal));


            return dt;
        }

        private void DeleteMediaPlanAdvCinemaSP(MediaPlan mp, List&lt;int&gt; setNumberList, int? currentSetNumber, bool DeleteCompletly)
        {
            List&lt;MediaPlanAdvCinema&gt; toDelete = null;
            if (setNumberList != null)
            { toDelete = GetListOfMediaPlanAdvCinema(mp, setNumberList, true); }
            else
            { toDelete = GetListOfMediaPlanAdvCinema(mp, currentSetNumber.Value, false); }


            DataTable dt = new DataTable("_MediaPlanAdvIDs");
            dt.Columns.Add(new DataColumn("ID"));
            if (toDelete != null &amp;&amp; toDelete.Count &gt; 0)
            {
                toDelete.ToList().ForEach(a =&gt;
                {
                    DataRow dr = dt.NewRow();
                    dr["ID"] = a.ID;
                    dt.Rows.Add(dr);
                });
                ;

                string connString = CommonController.AuthenticationInfo.ConnectionStrings[GlobalVariables.OMG_DATABASE];
                System.Data.SqlClient.SqlConnection sql = new System.Data.SqlClient.SqlConnection(connString);
                System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("dbo.MediaPlanAdvCinemaCanDelete", sql);
                cmd.CommandType = CommandType.StoredProcedure;
                System.Data.SqlClient.SqlParameter sp = cmd.Parameters.AddWithValue("@TableVariable", dt);
                bool can = false;
                System.Data.SqlClient.SqlParameter sp0 = cmd.Parameters.AddWithValue("@CanDelete", can);
                sp0.Direction = ParameterDirection.Output;
                sp.SqlDbType = SqlDbType.Structured;
                sql.Open();
                cmd.ExecuteNonQuery();
                var canDelete = cmd.Parameters["@CanDelete"].Value;
                sql.Close();
                if (((bool?)canDelete).HasValue &amp;&amp; ((bool?)canDelete).Value)
                {

                    System.Data.SqlClient.SqlConnection sql1 = new System.Data.SqlClient.SqlConnection(connString);
                    System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand("dbo.MediaPlanAdvCinemaDelete", sql1);
                    cmd1.CommandType = CommandType.StoredProcedure;
                    System.Data.SqlClient.SqlParameter sp1 = cmd1.Parameters.AddWithValue("@TableVariable", dt);
                    sp1.SqlDbType = SqlDbType.Structured;
                    sql1.Open();
                    cmd1.ExecuteNonQuery();
                    sql1.Close();

                    toDelete.ForEach(d =&gt;
                    {
                        if (d is MediaPlanAdvCinemaChimery &amp;&amp; mp.MediaPlanAdvCinemaChimeryList.Where(a =&gt; a.ID == d.ID).Count() &gt; 0)
                        {
                            mp.MediaPlanAdvCinemaChimeryList.Remove(d as MediaPlanAdvCinemaChimery);
                        }
                        if (d is MediaPlanAdvCinemaClient &amp;&amp; mp.MediaPlanAdvCinemaClientList.Where(a =&gt; a.ID == d.ID).Count() &gt; 0)
                        {
                            mp.MediaPlanAdvCinemaClientList.Remove(d as MediaPlanAdvCinemaClient);
                        }
                        if (d is MediaPlanAdvCinemaShopping &amp;&amp; mp.MediaPlanAdvCinemaShoppingList.Where(a =&gt; a.ID == d.ID).Count() &gt; 0)
                        {
                            mp.MediaPlanAdvCinemaShoppingList.Remove(d as MediaPlanAdvCinemaShopping);
                        }
                        if (d is MediaPlanAdvCinemaPostbuy &amp;&amp; mp.MediaPlanAdvCinemaPostbuyList.Where(a =&gt; a.ID == d.ID).Count() &gt; 0)
                        {
                            mp.MediaPlanAdvCinemaPostbuyList.Remove(d as MediaPlanAdvCinemaPostbuy);
                        }
                        if (d is MediaPlanAdvCinemaPriceList &amp;&amp; mp.MediaPlanAdvCinemaPriceListList.Where(a =&gt; a.ID == d.ID).Count() &gt; 0)
                        {
                            mp.MediaPlanAdvCinemaPriceListList.Remove(d as MediaPlanAdvCinemaPriceList);
                        }
                    });
                }
            }
        }

    }
}

--&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-7423819187200655602?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/7423819187200655602/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=7423819187200655602&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7423819187200655602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7423819187200655602'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/03/multidelete-z-uzyciem-zmiennej.html' title='Multidelete z użyciem zmiennej tablicowej'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3016829992464312644</id><published>2011-03-04T23:40:00.008+01:00</published><updated>2011-03-28T23:47:13.804+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>'Spłaszczanie' listy do opisu oddzielonego przecinkami</title><content type='html'>Jakby to nazwać &lt;b&gt;  ?&lt;/b&gt;
Problem jest taki: mamy np 10 kontaktów spełniających jakieś nasze wymagania i chcemy wyświetlić ta informacje w postali listy nazwisk oddzielonych przecinkami.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;span style="font-weight:bold;"&gt;C#&lt;/span&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
        StringBuilder sb = new StringBuilder();
        m_ContactList.ToList().ForEach(c =&gt; sb.Append(c.FirstName + "; "));
        m_FirstNameDecription = sb.ToString();
&lt;/pre&gt;
&lt;span style="font-weight:bold;"&gt;SQL&lt;/span&gt;
&lt;pre name="code" class="brush:sql;"&gt;
--1
Select top 10 FirstName from Contact Where SexID =1


--2
select top 1  a from Contact cross apply (
 select top 10 convert( nvarchar(100) , c.FirstName) + ', ' 
   from Contact c
   where c.SexID =1
  for xml path ('')
 ) e (a)

&lt;/pre&gt;
&lt;span style="font-weight:bold;"&gt;Wynik z SQLa&lt;/span&gt;
&lt;pre name="code" class="brush:text;"&gt;
--1
FirstName
---------------------------------------------------------------------------
Václav
Lubomír
Viktor
Karel
Vlastimil
Aleš
Milan
Vilém
František
Roman

(10 row(s) affected)


--2
a
---------------------------------------------------------------------------

Václav, Lubomír, Viktor, Karel, Vlastimil, Aleš, Milan, Vilém, František, Roman, 

(1 row(s) affected)
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3016829992464312644?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3016829992464312644/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3016829992464312644&amp;isPopup=true' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3016829992464312644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3016829992464312644'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/03/spaszczanie-listy-do-opisu-oddzielonego.html' title='&apos;Spłaszczanie&apos; listy do opisu oddzielonego przecinkami'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-1619682306113920582</id><published>2011-03-03T22:31:00.017+01:00</published><updated>2011-03-04T20:03:09.575+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><title type='text'>nHibernate named queries </title><content type='html'>&lt;b&gt; nHibernate named queries &lt;sql-query/&gt; &lt;/b&gt;
Czasem wymagania biznesowe skłaniają programistów do tworzenia bardzo skomplikowanych powiązań między obiektami / zapytań. 
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Aby mieć je w jakimś 'przewidywalnym miejscu a nie rozrzucone po kodzie możemy użyć &lt; query/&gt; w mappingu.&lt;Br/&gt;
Query jest niezależne od Class.

&lt;pre name="code" class="brush:xml;"&gt;
&lt; ?xml version="1.0" ?&gt;
&lt; hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo"  &gt;
  &lt; class name="OH.BusinessObjects.Subject, BusinessObjects" table="Subject" where="IsDeleted = 0" dynamic-update="false" dynamic-insert="false" &gt;
   &lt; id name="ID" column="ID" type="long" unsaved-value="0"&gt;
      &lt; generator class="identity"/&gt;
    &lt; / id&gt;
  &lt; / class&gt;

  &lt; query name="qSubjectByName"&gt;
       from Subject s
       where s.Name like :name
  &lt; / query&gt;

&lt; / hibernate-mapping&gt;

&lt;/pre&gt;
Wywołanie mogło by być w ten deseń:
&lt;pre name="code" class="brush:c-sharp;"&gt;
IQuery query = Session.GetNamedQuery("qSubjectByName");
query.SetParameter("name","SomeName");
var list = query.List&lt; Subject&gt;();
&lt;/pre&gt;
Ale co jeśli powiązania pomiędzy tabelami nie są tak oczywiste aby móc z nich skorzystać w nHibernate. Być może powiązania są tylko logiczne bez kluczy obcych. Lub nasze zapytanie jest na tyle skomplikowane że warto użyć SQLa aby go zoptymalizować.&lt;br/&gt;
Mamy &lt; sql-query /&gt;
&lt;pre name="code" class="brush:xml;"&gt;
&lt; ?xml version="1.0" ?&gt;
&lt; hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo"  &gt;
  &lt; class name="OH.BusinessObjects.Subject, BusinessObjects" table="Subject" where="IsDeleted = 0" dynamic-update="false" dynamic-insert="false" &gt;
   &lt; id name="ID" column="ID" type="long" unsaved-value="0"&gt;
      &lt; generator class="identity"/&gt;
    &lt; / id&gt;
  &lt; / class&gt;

  &lt; sql-query name="qMediumSubjecList"&gt; 
    &lt; return alias="s" class="OH.BusinessObjects.Subject, BusinessObjects"/&gt; 
    &lt; ![CDATA[
             SELECT s.* 
             FROM Subject s
             inner join SubjectAddress sa on sa.SubjectID = s.ID and s.IsCurrent=1   and s.IsDeleted = 0 and sa.IsDeleted =0
             INNER JOIN Contact c ON sa.SelfInstanceGUID = c.SubjectAddressSelfInstanceGUID and c.IsDeleted=0
             INNER JOIN Medium m on c.MediumID = m.ID and m.IsDeleted =0
             WHERE 
                   m.ID = :mediumID
     ]]&gt; 
  &lt; / sql-query&gt; 
&lt; / hibernate-mapping&gt;

&lt;/pre&gt;
Kluczowe jest &lt;span style="font-weight:bold;"&gt;[CDATA[&lt;/span&gt; które zawiera dowolne zapytanie SQL.&lt;br/&gt;
Kolejnym fajnym elementem jest &lt;span style="font-weight:bold;"&gt;return&lt;/span&gt; któremu z łatwością możemy określić klasę której się spodziewamy jako wyniku.&lt;br/&gt;
Wywołanie jest równie łatwe jak poprzednio

&lt;pre name="code" class="brush:c-sharp;"&gt;
   IQuery query = Session.GetNamedQuery("qMediumSubjecList"); 
   query.SetInt64("mediumID", MediumID); 
   var list = query.List&lt; Subject&gt;(); 
&lt;/pre&gt;

Możemy też zwrócić pojedyncze kolumny

&lt;pre name="code" class="brush:xml;"&gt;
 &lt; sql-query name="qSubjectLockingInfo"&gt; 
   &lt; return-scalar column="LastChangeDate" type="datetime"/&gt; 
   &lt; return-scalar column="LockedSessionID" type="Guid"/&gt; 
   &lt; ![CDATA[
            SELECT m.LastChangeDate AS LastChangeDate 
                 , m.LockedSessionID AS LockedSessionID
            FROM Subject m 
            WHERE m.ID = :subjectID
   ]]&gt; 
 &lt; / sql-query&gt;
&lt;/pre&gt;

A jeśli będziemy posiadać klasę z odpowiednimi dwoma propercjami - możemy przetransformować wynik na klasę i transformer.
&lt;pre name="code" class="brush:c-sharp;"&gt;
  public class LockingInfo
    {
        public virtual DateTime LastChangeDate
        {
            get;
            set;
        }

        public virtual Guid? LockedSessionID
        {
            get;
            set;
        }
    }


    public class LockingInfoResultTransformer : IResultTransformer
    {

        #region IResultTransformer Members

        public IList TransformList(IList collection)
        {

            return collection == null ? null : collection.OfType&lt; LockingInfo&gt;().ToList();
        }

        public object TransformTuple(object[] tuple, string[] aliases)
        {
            if (tuple == null || tuple.Length == 0 || aliases == null || aliases.Length == 0)
            {
                return null;
            }

            LockingInfo ret = new LockingInfo();
            for (int i = 0; i &lt; aliases.Length; i++ )
            {
                switch (aliases[i])
                {
                    case "LastChangeDate": ret.LastChangeDate = (DateTime)tuple[i];
                        break;
                    case "LockedSessionID": ret.LockedSessionID = (Guid?)tuple[i];
                        break;
                }
            }
            return ret;
        }

        #endregion
    }
&lt;/pre&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
    Query query = session.GetNamedQuery("qSubjectLockingInfo"); 
    query.SetInt64("subjectID", ID); 
    query.SetResultTransformer(new LockingInfoResultTransformer()); 

    LockingInfo lockInfo = query.UniqueResult&lt; LockingInfo&gt;(); 
&lt;/pre&gt;
&lt;a href="http://docs.jboss.org/hibernate/core/3.5/reference/en/html/querysql.html"&gt;Na koniec link do dokumentacji tutaj.&lt;/a&gt;
i słowo o LinqToSQL &lt;a href="http://aspguy.wordpress.com/2008/08/15/speed-up-linq-to-sql-with-compiled-linq-queries/"&gt;tuta znajdziemy wpis o nazwanych query w LinqToSQL&lt;/a&gt; wydaje się jednak że można to porównać do &lt; query&gt; z nHibbernata, natomiast nie udało mi się znaleźć odpowiednika &lt; sql-query&gt;.

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-1619682306113920582?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/1619682306113920582/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=1619682306113920582&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1619682306113920582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1619682306113920582'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/03/nhibernate-named-queries.html' title='nHibernate named queries &lt;sql-query/&gt;'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-5364032941421048944</id><published>2011-03-02T22:32:00.009+01:00</published><updated>2011-03-04T23:26:48.047+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Problem ograniczenie 2100 parametrów.</title><content type='html'>&lt;b&gt;  
Przy problemie 2100 parametrów w LinqToSQL zrodziły się we mnie wątpliwości czy powiedzenie  że każdy kod został już napisany i wystarczy go znaleźć jest prawdziwe. 
&lt;/b&gt;
&lt;br/&gt;
Ale w czym rzecz. Komu by przyszło do głowy wpisywać przeszło dwa tysiące parametrów? Być może nie jest to wygodne rozwiązanie jeśli piszemy warunek &lt;br/&gt;
Name like 'a' Or Name like 'b'&lt;br/&gt;
Ale jeśli weźmiemy &lt;span style="font-weight:bold;"&gt;Contains &lt;/span&gt;(czyli po Sqlowemu &lt;span style="font-weight:bold;"&gt;IN&lt;/span&gt;) i np zestaw IDków lub GUIDów to już nie jest takie niedorzeczne.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
private IQueryable GetList()
{
     ContactDataContext cdc = new ContactDataContext(GlobalVariables.ConnectionString);
     cdc.ObjectTrackingEnabled = false;

     long[] ids = new long[]{1,2,...,2200};            
     var result = from cl in cldc.ContactLists
                  where !cl.IsDeleted
                        &amp;&amp; ids.Contains(cl.ID)
                  select cl;
          return result;
}
&lt;/pre&gt;
KaBum.
&lt;br/&gt;
Rozwiązanie znalazłam tutaj &lt;a href="http://net-application-development-blog.altoros.com/linq-to-sql-alternative-for-the-where-in-expression/"&gt;- jedyne znalezione rozwiązanie.&lt;/a&gt;&lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Idea&lt;/span&gt; &lt;br/&gt;
No przecież idealnie było by mieć nasz zbiór idków w jakiejś tabeli i się do niej join'ąć. &lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Problem&lt;/span&gt; &lt;br/&gt;
Listę idków mamy po stronie aplikacji a przecież zapytanie wykona się po stronie bazy danych więc listę trzeba przetransportować do bazy.
&lt;span style="font-weight:bold;"&gt;&lt;br/&gt;
Rozwiązanie &lt;/span&gt;&lt;br/&gt;
Banał - wysłać listę do bazy, ale skoro nie możemy jako parametry to jak?&lt;br/&gt;
Stwórzmy jeden parametr typu XML i zapiszmy w tabelce tymczasowej - dzięki temu będziemy mieć się do czego join'ować z aplikacji.&lt;br/&gt;
Great. Rozwiązanie działa. &lt;br/&gt;
&lt;span style="font-weight:bold;"&gt;Ale&lt;/span&gt; &lt;br/&gt;
Okazało się że operacja dominująca w tym rozwiązaniu czyli Insert działa bardzo wolno. Praktycznie przy 2,5 tys rowków był to czas rzędu 20 sekund co praktycznie wyklucza rozwiązanie.&lt;br/&gt;
&lt;br/&gt;
Dzięki wsparciu kolegi o wiedzy z SQLa znacznie większej niż moja, okazało się że wystarczy pominąć tabelkę tymczasową.
&lt;br/&gt;
Oto pełne rozwiązanie.&lt;br/&gt;

&lt;pre name="code" class="brush:sql;"&gt;
ALTER FUNCTION [dbo].[udf_ParseIDs]
(@ids xml)
RETURNS --@temp
--TABLE(Id bigint)
--BEGIN
--  INSERT INTO @temp(id) -- ten insert był zbyt kosztowny!

table as return(
  SELECT
   Id.value('.', 'bigint') as ID
  FROM
   @ids.nodes('/ArrayOfLong/long')  list(id)
  --RETURN
)
&lt;/pre&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
private IQueryable GetList()
{
     ContactDataContext cdc = new 
                             ContactDataContext(GlobalVariables.ConnectionString);
     cdc.ObjectTrackingEnabled = false;
       
     long[] ids = new long[]{1,2,...,2200};  
     System.Xml.Linq.XElement  serialized = GetIDsAsXml(ids);
     var result = from c in cdc.ContactLists
                  join ids in cdc.udf_ParseIDsMediaPlan(serialized)
                  on c.ID equals ids.ID
                  where !c.IsDeleted &amp;&amp;
                  select c;
     return result;
}

///Stworzenie elementu xml z listy longów
public static XElement SerializeGuidList(IList&lt;long&gt; ids)
{
    using (var sw = new System.IO.StringWriter())
    {
        var guidArraySerializer = new XmlSerializer(typeof(long[]));
        guidArraySerializer.Serialize(sw, ids.ToArray());
        using (var sr = new System.IO.StringReader(sw.ToString()))
        {
            return XElement.Load(sr);
        }
    }
}

&lt;/pre&gt;
A to już efekt przechwycony profilerem (troszkę przycięty xml):
&lt;pre name="code" class="brush:sql;"&gt;
declare
@p3 xml 
set
@p3=convert(xml,N'&lt;ArrayOfLong xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;&lt;long&gt;1&lt;/long&gt;&lt;long&gt;3&lt;/long&gt;&lt;long&gt;5&lt;/long&gt;&lt;long&gt;10&lt;/long&gt;&lt;long&gt;12&lt;/long&gt;&lt;long&gt;13&lt;/long&gt;&lt;long&gt;14&lt;/long&gt;&lt;long&gt;15&lt;/long&gt;&lt;long&gt;17&lt;/long&gt;&lt;long&gt;18&lt;/long&gt;&lt;long&gt;22&lt;/long&gt;&lt;long&gt;25&lt;/long&gt;&lt;long&gt;26&lt;/long&gt;&lt;long&gt;28&lt;/long&gt;&lt;long&gt;29&lt;/long&gt;&lt;long&gt;30&lt;/long&gt;&lt;long&gt;32&lt;/long&gt;&lt;long&gt;33&lt;/long&gt;&lt;long&gt;34&lt;/long&gt;&lt;long&gt;35&lt;/long&gt;&lt;long&gt;36&lt;/long&gt;&lt;long&gt;38&lt;/long&gt;&lt;long&gt;39&lt;/long&gt;&lt;long&gt;40&lt;/long&gt;&lt;long&gt;41&lt;/long&gt;&lt;long&gt;44&lt;/long&gt;&lt;long&gt;45&lt;/long&gt;&lt;long&gt;47&lt;/long&gt;&lt;long&gt;48&lt;/long&gt;&lt;long&gt;50&lt;/long&gt;&lt;long&gt;52&lt;/long&gt;&lt;long&gt;54&lt;/long&gt;&lt;long&gt;57&lt;/long&gt;&lt;long&gt;58&lt;/long&gt;&lt;long&gt;60&lt;/long&gt;&lt;long&gt;61&lt;/long&gt;&lt;long&gt;62&lt;/long&gt;&lt;long&gt;63&lt;/long&gt;&lt;long&gt;64&lt;/long&gt;&lt;long&gt;65&lt;/long&gt;&lt;long&gt;66&lt;/long&gt;&lt;long&gt;73&lt;/long&gt;&lt;long&gt;74&lt;/long&gt;&lt;long&gt;77&lt;/long&gt;&lt;long&gt;78&lt;/long&gt;&lt;long&gt;79&lt;/long&gt;&lt;long&gt;80&lt;/long&gt;&lt;long&gt;83&lt;/long&gt;&lt;long&gt;84&lt;/long&gt;&lt;long&gt;85&lt;/long&gt;&lt;long&gt;86&lt;/long&gt;&lt;long&gt;87&lt;/long&gt;&lt;long&gt;88&lt;/long&gt;&lt;long&gt;89&lt;/long&gt;&lt;long&gt;90&lt;/long&gt;&lt;long&gt;91&lt;/long&gt;&lt;long&gt;92&lt;/long&gt;&lt;long&gt;93&lt;/long&gt;&lt;long&gt;94&lt;/long&gt;&lt;long&gt;95&lt;/long&gt;&lt;long&gt;96&lt;/long&gt;&lt;long&gt;97&lt;/long&gt;&lt;long&gt;98&lt;/long&gt;&lt;/ArrayOfLong&gt;') 
exec
sp_executesql N'SELECT [t0].[ID], [t0].[CreatedBy], [t0].[CreateDate], [t0].[IsDeleted] 
FROM [dbo].[Contact] AS [t0]
INNER JOIN [dbo].[udf_ParseIDs](@p0) AS [t1] ON ([t0].[ID]) = [t1].[Id]
ORDER BY [t0].[ID]'
,N'@p0 xml',@p0=@p3
&lt;/pre&gt;
Ciekawy problem i ciekawe rozwiązanie (i szybkie).
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-5364032941421048944?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/5364032941421048944/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=5364032941421048944&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5364032941421048944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5364032941421048944'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2011/03/problem-ograniczenie-2100-parametrow.html' title='Problem ograniczenie 2100 parametrów.'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8439080955933237876</id><published>2010-08-31T23:32:00.005+02:00</published><updated>2010-08-31T23:40:51.230+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Enum to List</title><content type='html'>Konwersja Enum do List. Zawsze zapominam jak to się robi a to tak prosta sprawa.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
IList&lt; DayOfWeek &gt; listDayOfWeek = new List&lt; DayOfWeek &gt;();
var dic = Enum.GetValues(typeof(DayOfWeek)) //pobiera wszystkie wartości z danego typu
           as IEnumerable&lt; DayOfWeek &gt;; //!! najważniejszy punkt programu

// a teraz dodajmy warunek że nasza lista ma być.. np bez niedzieli
listDayOfWeek = dic.Where(d=&gt;d!= DayOfWeek.Sunday).ToList();
&lt;/pre&gt;
&lt;!--http://devlicio.us/blogs/joe_niland/archive/2006/10/10/Generic-Enum-to-List_3C00_T_3E00_-converter.aspx--&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8439080955933237876?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8439080955933237876/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8439080955933237876&amp;isPopup=true' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8439080955933237876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8439080955933237876'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/08/enum-to-list.html' title='Enum to List'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-5676379657236524938</id><published>2010-08-31T23:07:00.004+02:00</published><updated>2010-08-31T23:28:41.386+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wszystko i nic'/><title type='text'>JavaScript + Debug + VS2008 +IE8</title><content type='html'>&lt;b&gt;  &lt;/b&gt;
Debugowanie aplikacji ASP w Visual Studio 2008 z użyciem IE8 może być denerwujące, a nawet uciążliwe. A to za sprawą tymczasowych skryptów (i innych dynamiczne dokumenty) które skaczą w solutionie (a przy okazji spowalniają proces debugu).&lt;br/&gt;
Jeśli używamy powyższej kombinacji to debugowanie skryptów jest default = ON i nie ma opcji jego wyłączenia.
&lt;br/&gt;
Jest kilka obejść tego problemu &lt;a href="http://blogs.msdn.com/b/greggm/archive/2009/04/06/disabling-script-debugging-in-vs-2008-ie8.aspx"&gt;tutaj&lt;/a&gt;

&lt;br/&gt;
Najprostszym rozwiązaniem jest zainstalowanie &lt;b&gt;Silverlight Tools&lt;/b&gt; 
i zaznaczenie opcji debugowania Silverlighta (opcja na samym dole po prawej).
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/TH1y1fV9VLI/AAAAAAAAAJg/Grwsnt8twRk/s1600/Untitled5.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/TH1y1fV9VLI/AAAAAAAAAJg/Grwsnt8twRk/s320/Untitled5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5511687782243587250" /&gt;&lt;/a&gt;

Dlaczego to pomaga? debugger nie potrafi na raz debugować Silverlighta i JavaScriptów. &lt;br/&gt;
Proste a przydatne&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-5676379657236524938?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/5676379657236524938/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=5676379657236524938&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5676379657236524938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5676379657236524938'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/08/javascript-debug-vs2008-ie8.html' title='JavaScript + Debug + VS2008 +IE8'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lJKm6y9ygyE/TH1y1fV9VLI/AAAAAAAAAJg/Grwsnt8twRk/s72-c/Untitled5.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2934489110895409311</id><published>2010-08-09T22:48:00.007+02:00</published><updated>2010-08-11T23:02:25.083+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Kopiowanie POCO</title><content type='html'>&lt;b&gt;Kopiowanie obiektów &lt;/b&gt;mogło by się wydawać prostą sprawą, jednak powracając do podstaw języka przypomnimy sobie o referencjach.
&lt;br/&gt;
Na początek przytocze bardzo fajny i pomocny artykuł &lt;a href="http://ondotnet.com/pub/a/dotnet/2002/11/25/copying.html?page=1"&gt;Copying, Cloning, and Marshalling in .NET&lt;/a&gt;
Powyższy artykuł wspomina o tworzeniu płytkiej oraz głębokiej kopi.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
Aby wykonać płytką kopie nie trzeba wiele wysiłku ponieważ dostępna jest metoda &lt;i&gt;MemberwiseClone&lt;/i&gt;
public virtual MyCloneableClass Clone()
{
    // płytka kopia klasy
    MyCloneableClass x =  this.MemberwiseClone() as MyCloneableClass;
}
&lt;/pre&gt;
Po zrobieniu płytkiej kopi obiektu możliwe jest oczywiście zrobienie kopi wszystkich obiektów będących propercjami obiektu kopiowanego w celu uzyskania głębokiego kopiowania.&lt;br/&gt;
Można znaleźć kolekcje - Listę w propercjach obiektu korzystając z reflection.&lt;br/&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
public void Funcky (BusinessObject c)
{
                var p = c.GetType().GetProperties();
                foreach (PropertyInfo pro in p)
                {
                    MethodInfo mi = pro.GetGetMethod();
                    ICollection collection = mi.Invoke(c, null) as ICollection;
                    if (collection != null)
                    {
                        IEnumerator iter = collection.GetEnumerator();
                        while (iter.MoveNext())
                        {
                            if (iter.Current is BusinessObject)
                            { 
                                //Do something smart
                                //np płytką kopie obiektu
                            }
                        }
                    }
                }
}
&lt;/pre&gt;

Innym wyjściem jest napisanie funkcji serializującej i deserializującej obiekt kopiowany. Pamiętajmy o oznaczeniu klasy jako serializowalna.
&lt;pre name="code" class="brush:c-sharp;"&gt;
  [Serializable]
  public class MyCloneableClass {}

  public T DeepCopy&lt; T &gt;() 
  {
        MemoryStream memoryStream = new MemoryStream();
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, this);
        memoryStream.Seek(0, SeekOrigin.Begin);
        T objectCopy = (T)binaryFormatter.Deserialize(memoryStream);
        memoryStream.Close();
        return objectCopy;
  }&lt;/pre&gt;
Z takim głębokim kopiowaniem należy ostrożnie postępować jeśli używamy jakichś obiektów które są leniwie ładowane ;)

&lt;!--
http://andrzej.net.pl/index.php/2010/01/shallow-copy-a-deep-copy-klonowanie-obiektu-z-memberwiseclone-oraz-przy-uzyciu-serializacji/

http://ondotnet.com/pub/a/dotnet/2002/11/25/copying.html?page=1
http://blogsprajeesh.blogspot.com/2008/07/generic-implementation-of-deep-and.html




http://andrzej.net.pl/index.php/2010/01/shallow-copy-a-deep-copy-klonowanie-obiektu-z-memberwiseclone-oraz-przy-uzyciu-serializacji/ --&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2934489110895409311?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2934489110895409311/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2934489110895409311&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2934489110895409311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2934489110895409311'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/08/kopiowanie-poco.html' title='Kopiowanie POCO'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-9204698863713922669</id><published>2010-08-09T22:36:00.000+02:00</published><updated>2010-08-09T22:37:42.988+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Dziedziczenie a nHibernate/LinqToSql</title><content type='html'>Dziedziczenie może byc realizowane na wiele sposobów. 
Dziś: &lt;br/&gt;
&lt;b&gt;Table per class hierarchy - czyli wspólna tabela z dyskryminatorem   &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;

Załóżmy że mamy dwie klasy które docelowo mają różnić się tak naprawdę paroma polami (np każda z nich ma 5 swoich pól reszta jest wspólna). Najlogiczniejszym wyjściem jest dziedziczenie z klasy bazowej zawierającej wspólne pola.
&lt;br/&gt;
 Przy tak niewielkiej ilości pól nie-wspólnych dobrze jest mieć (naprawdę z wielu praktycznych powodów) jedną tabelę w bazie danych dla obu klas.&lt;br/&gt;
Aby przenieść całą sytuację do nHibernata lub linqa potrzebne jest dodatkowe pole tak zwany &lt;b&gt;dyskryminator&lt;/b&gt; dzięki któremu będziemy wiedzieli po stronie bazy danych z którym typem klasy mamy do czynienia.
&lt;br/&gt;
&lt;br/&gt;
Moją klasą bazową będzie Invoice, natomiast dziedziczące InvoiceIssued oraz InvoceReceived.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/TE89zSQZCQI/AAAAAAAAAI4/fVkTpzre3zY/s1600/Untitled2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 112px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/TE89zSQZCQI/AAAAAAAAAI4/fVkTpzre3zY/s320/Untitled2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5498681621325875458" /&gt;&lt;/a&gt;
 W nHibernate cała sprawa sprowadza się jak zawsze do dobrego pliku mapowania
&lt;pre name="code" class="brush:c-sharp;"&gt;

&lt;?xml version="1.0" encoding="utf-8"?&gt; 
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"&gt; 
&lt;class name="BusinessObjects.Invoice" table="Invoice" where="IsDeleted=0" dynamic-update="false" dynamic-insert="true" lazy="true"&gt; 
&lt;id name="ID" column="ID" type="long" unsaved-value="0"&gt; 
&lt;generator class="identity" /&gt; 
&lt;/id&gt; 
&lt;discriminator column="InvoiceTypeCode" not-null="true" type="string" force="true"/&gt; 

&lt;/pre&gt;
Słówko o dyskryminatorze tutaj. W pliku mapowań nHibernata nie możemy mieć dwa razy tego samego pola, dlatego też nie możemy mieć np oneToOneID oraz kolekcji oneToOne. Nie możemy mieć również propercji odwołującej się do tego samego pola w bazie na którym bazuje dyskryminator. Oczywiście po typie klasy wiemy z czym mamy do czynienia jednak czasem warto coś takiego wiedzieć również na poziomie klasy bazowej ja zastosowałam redundantne pole, choć zapewne rozwiązań jest wiele.

&lt;pre name="code" class="brush:c-sharp;"&gt;
//kontunuując poprzedni fragment kodu
&lt;property name="IssueDate" column="IssueDate" type="DateTime" /&gt; 
//... all common properties

&lt;subclass name="BusinessObjects.InvoiceIssued" discriminator-value="Ou"&gt; 
&lt;property name="HeaderText" column="HeaderText" type="string" /&gt; 
&lt;/subclass&gt;
 
&lt;subclass name="BusinessObjects.InvoiceReceived" discriminator-value="In"&gt; 
&lt;property name="Notes" column="Notes" type="string" /&gt; 
&lt;property name="ReceiveDate" column="ReceiveDate" type="DateTime" /&gt; 
&lt;/subclass&gt; 
&lt;/class&gt; 
&lt;/hibernate-mapping&gt;
&lt;/pre&gt;

I to by było na tyle. Nie ma żadnej filozofii. Ponieważ klasy mamy trzy Invoice, InvoiceIssued, InvoiceReceived - możemy się nimi dowolnie posługiwać.
&lt;br/&gt;
Nie ma też żadnej filozofii w pobieraniu obiektów/list. nHibernatowi jest wszytko jedno czy chcemy pobrać sobie klase Invoice czy InvoiceIssued. O nic więcej nie trzeba się martwić (no chyba że o utrzymanie redundantnych pól w atomowej jedności - ale to przecież tylko w wypadku gdy sami tak zadecydujemy).
&lt;pre name="code" class="brush:c-sharp;"&gt;
var Invoice i =Session.Get&lt;Invoice&gt;(ID);
var InvoiceReceived ir =Session.Get&lt;InvoiceReceived&gt;(ID);
&lt;/pre&gt;
&lt;hr/&gt;
&lt;b&gt;To teraz to samo zadanie w LinqToSql.&lt;br/&gt;&lt;/b&gt;
Ponieważ mamy tutaj możliwość przeciągnij upuść pozmieniaj - przeciągamy sobie tabelkę a powstała klasa będzie naszą bazową. (Z przyczyn realnego użycia projektowego klasy tym razem nazywają się InvoiceList, InvoiceIssuedList, InvoiceReceivedList). Należy dodać klasy które będą dziedziczyć z bazowej, oznaczyć relacje a następnie wyciąć specyficzne propercje i przenieść do odpowiednich klas.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/TGBgp9gvigI/AAAAAAAAAJA/ilb08L6rhRs/s1600/Untitled2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 140px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/TGBgp9gvigI/AAAAAAAAAJA/ilb08L6rhRs/s400/Untitled2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5503505018649545218" /&gt;&lt;/a&gt;

&lt;br/&gt;
W klasach dziedziczących  konieczne jest wskazanie które pole będzie dyskryminatorem -&lt;i&gt;Discriminator Property&lt;/i&gt; oraz jaka wartości dyskryminatora jest odpowiednia dla danej klasy -&lt;i&gt;Derived Class Discriminator Value&lt;/i&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/TGBicOed08I/AAAAAAAAAJI/fuCLKhCmBZ4/s1600/Untitled3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 340px; height: 200px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/TGBicOed08I/AAAAAAAAAJI/fuCLKhCmBZ4/s400/Untitled3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5503506981708485570" /&gt;&lt;/a&gt;
&lt;br/&gt;
Ważna sprawa - jedna z klas dziedziczących musi być defaultowa - należy określić wartość &lt;i&gt; Inheritance Default&lt;/i&gt;. &lt;br/&gt;
Związane jest to z generowanymi zapytaniami sql. Choć pewnie chcielibyśmy często inaczej to LinqToSql dla klas dziedziczących zadaje zapytanie sql &lt;br/&gt;
PoleDyskryminatora='kodDyskryminatora' jeśli klasa nie jest default oraz &lt;br/&gt;
PoleDyskryminatora&lt;&gt;'kodDyskryminatora' jeśli klasa jest default.&lt;br/&gt;
(Przyznaje że przypadek testowany był dla dwóch klas dziecziczących być może w przypadku większej ilości klas jest inaczej.)
&lt;br/&gt;
&lt;br/&gt;
Było mi ciężko do tego wszystkiego dojść z wizualnego 'ułatwiacza' pracy, dlatego chciałam przedstawić części wygenerowanego pliku mapowań gdzie wszytko jest czarno na białym (no może kolorowo na szarym ale to kwestia ustawień).
&lt;br/&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
[Table(Name="dbo.Invoice")] 
[InheritanceMapping(Code="Ou", Type=typeof(InvoiceIssuedList), IsDefault=true)] 
[InheritanceMapping(Code="In", Type=typeof(InvoiceReceivedList))] 
public partial class InvoiceList : INotifyPropertyChanging, INotifyPropertyChanged 
{
//...
  [Column(Storage="_InvoiceTypeCode", DbType="NVarChar(2) NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never, IsDiscriminator=true)] 
  public string InvoiceTypeCode 
  {
    get 
     {
       //...
     }
    }
  }
//...
}

public partial class InvoiceIssuedList : InvoiceList 
{
//...
}

public partial class InvoiceReceivedList : InvoiceList 
{
//...
}
&lt;/pre&gt;
&lt;br/&gt;
Ostatnia sprawa to wyciągnięcie z Linq'a tego co akurat byśmy chcieli. &lt;br/&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
public
IQueryable GetInvoiceIssuedList() 
{
InvoicingListLinqDataContext context = new InvoicingListLinqDataContext(ConnectionStrings[GlobalVariables._DATABASE]); 
context.ObjectTrackingEnabled = false; 
var ret = from s in context.InvoiceLists. //...
&lt;/pre&gt;
I oto zdziwienie - w contexcie nie ma InvoiceReceivedList ani InvoiceIssuedList. Jest jedynie InvoiceLists
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/TGBlxKDu15I/AAAAAAAAAJQ/5zJkdB2IjtQ/s1600/Untitled1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 178px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/TGBlxKDu15I/AAAAAAAAAJQ/5zJkdB2IjtQ/s400/Untitled1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5503510639834748818" /&gt;&lt;/a&gt;
Okazuje się że należy odpytać kontekst o InvoiceLists dodatkowo podając typ który tak naprawdę chcemy wyciągnąć.
&lt;pre name="code" class="brush:c-sharp;"&gt;
public
IQueryable GetInvoiceIssuedList() 
{
  InvoicingListLinqDataContext context = new InvoicingListLinqDataContext(ConnectionStrings[GlobalVariables._DATABASE]); 
  context.ObjectTrackingEnabled = false; 
  var ret = from s in context.InvoiceLists.OfType&lt;InvoiceIssuedList&gt;() 
  where !s.IsDeleted 
  select s; 
  return ret; 
} 
&lt;/pre&gt;

&lt;br/&gt;
Z mojego punktu widzenia przyjemniejsze rozwiązanie stanowi nHibernate - jednak nad gustami się nie dyskutuje ;)

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-9204698863713922669?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/9204698863713922669/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=9204698863713922669&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9204698863713922669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9204698863713922669'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/08/dziedziczenie-nhibernatelinqtosql.html' title='Dziedziczenie a nHibernate/LinqToSql'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lJKm6y9ygyE/TE89zSQZCQI/AAAAAAAAAI4/fVkTpzre3zY/s72-c/Untitled2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8756552440667003935</id><published>2010-07-22T23:26:00.007+02:00</published><updated>2010-07-23T01:17:22.971+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><title type='text'>Linq nHibernate i DevExpress grid z ServerMode</title><content type='html'>Co innego poznawać technologie na prostych przykładach a co innego zmierzyć się z konkretnym problemem.
&lt;br/&gt;
Windowsowy grid od DevExpressa ma jedną bardzo ciekawą i przydatną funkcjonalność - &lt;b&gt;  ServerMode&lt;/b&gt;. A polega to na tym że jeśli grid jako dataSource ma podpięty LinqDataSource i ustawioną propercje ServerMode, to sam sobie radzi z dynamicznym stronicowiem czyli zaciąga sobie tylko dane które aktualnie wyświetla. 
&lt;br/&gt;
Fajnie. Dodajmy do tego wyszukiwanie (oczywiście tego wbudowanego do grida aby wszytko razem działało), i jeszcze jeden drobny szczegół - normalizacje bazy danych.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Taka mała struktura w której Nazwa subiekta przechowywana jest w osobnej tabeli. 
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/TEi_5o_kFAI/AAAAAAAAAIg/HvV40kdkL0E/s1600/subject1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 297px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/TEi_5o_kFAI/AAAAAAAAAIg/HvV40kdkL0E/s320/subject1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5496854342183162882" /&gt;&lt;/a&gt;
Chcemy więc wyświetlić dane z tabeli parenta oraz nazwę z tabeli childa (tak naprawdę powiązannie będzie 1:1 zawsze tylko jeden child jest aktualny).
&lt;br/&gt;
Skoro tylko jeden child jest aktualny można by więc zrobić propercję na poziomie parenta, która będzie zwracać Name z childa.
&lt;br/&gt;
Tworzymy więc partial class dla naszego Subject i dopisujemy:
&lt;pre name="code" class="brush:c-sharp;"&gt;
public string Name
{
    get{ return SubjectNameNIPs.DefaultIfNull(new SubjectNameNIP()).FirstOrDefault().Name;}
}
&lt;/pre&gt;
Takie rozwiązanie działa. Wprawdzie nie wypróbowałam wyszukiwania po takim atrybucie, jednak to by było i tak za proste ;)
&lt;br/&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
SubjectListLinqDataContext context = new SubjectListLinqDataContext(ConnectionStrings[DATABASE_NAME]); 
context.ObjectTrackingEnabled = false;
&lt;/pre&gt;
Właściwość &lt;b&gt;ObjectTrackingEnabled = false &lt;/b&gt; sygnalizuje DataContext żeby nie pamiętał zmian jakie zachodzą w obiektach. Z jednej strony zyskujemy dodatkowy przyrost wydajności dla list które same w sobie nie wymagają pamiętania stanu z drugiej strony... umożliwiamy odświeżenie listy po modyfikacji obiektu inną metodą niż przy użyciu linqa.
&lt;br/&gt; Jednak Name - przestaje działać.
&lt;br/&gt;
Dzieje się tak ponieważ jeśli ObjectTrackingEnabled = false to również  DeferredLoadingEnabled = false i wtedy aby załadować childy pozostaje &lt;b&gt;LoadWith&lt;/b&gt;
&lt;br/&gt;
Od razu analogiczną sytuacją wydała mi się nHibernatowa StatelessSession.
&lt;br/&gt;
Spróbujmy więc &lt;b&gt; LoadWith&lt;/b&gt;
&lt;br/&gt; 

&lt;pre name="code" class="brush:c-sharp;"&gt;
SubjectListLinqDataContext context = new SubjectListLinqDataContext(ConnectionStrings[DATABASE_NAME]); 
context.ObjectTrackingEnabled = false;
var lo = new System.Data.Linq.DataLoadOptions();
lo.LoadWith&lt;
SubjectList&gt;(a =&gt; a.SubjectNameNIPs);
,context.LoadOptions = lo;
&lt;/pre&gt;
Sukces. Przefiltrujmy po polu Name... porażka.
&lt;br/&gt;
Grid nie potrafił zadać zapytania, za bardzo mnie to nie dziwi szczególnie jeśli warunek wyboru aktualnego childa jest bardziej skomplikowany.
&lt;br/&gt;
Moje pomysły się wyczerpały, dlatego logika tego połączenia została przeniesiona do bazy danych w postaci ComputedColumn dla którego formułę ustawić należy na wywołanie funkcji zwracającej Name z tabeli childów.
&lt;br/&gt;
Najszybszym rozwiązaniem (jeśli chodzi o wykonywanie zapytania na bazie) była by redundancja danych.
&lt;br/&gt;
Oczywiście można pisać własne selecty dla LinqToSql bądź widoki na bazie, jednak poszukiwane było rozwiązanie bardzo szybkie w realizacji a przeciągnij i ciesz sie DataContext wygłądało najbardziej obiecująco bez konieczności przeróbek.
&lt;br/&gt;
A gdzie w tm wszystkim jest nHibernate?
&lt;br/&gt;
Otórz w pliku mapowania nHibernate powiada opcje &lt;b&gt;Formula&lt;/b&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
&lt;property name="Name" formula="select s.Name from SubjectNameNIP s where s.SubjectID = ID " /&gt;
&lt;/pre&gt;
Jeśli jedynym twoim narzędziem jest młotek każdy problem wygląda jak gwóźdź.
&lt;br/&gt;
Ja powiększyłam zasób różnorodnych gwoździ.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8756552440667003935?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8756552440667003935/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8756552440667003935&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8756552440667003935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8756552440667003935'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/07/linq-nhibernate-i-devexpress-grid-z.html' title='Linq nHibernate i DevExpress grid z ServerMode'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/TEi_5o_kFAI/AAAAAAAAAIg/HvV40kdkL0E/s72-c/subject1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8321824147351013686</id><published>2010-03-27T21:39:00.004+01:00</published><updated>2010-03-27T21:45:10.369+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Params</title><content type='html'>&lt;b&gt;Params &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
public static void UseParams(params int[] list)
    {
        for (int i = 0; i &lt; list.Length; i++)
        {
            Console.Write(list[i] + " ");
        }
        Console.WriteLine();
    }

public void CallUseParams()
{
    UseParams(1, 2, 3, 4);
}
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8321824147351013686?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8321824147351013686/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8321824147351013686&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8321824147351013686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8321824147351013686'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/03/params.html' title='Params'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8749050659606441157</id><published>2010-02-22T20:55:00.005+01:00</published><updated>2010-03-27T20:06:03.885+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wszystko i nic'/><title type='text'>Koder na wspomagaczach</title><content type='html'>Widziałam kilka prezentacji gdzie zachwycano się wspomagaczami takimi jak Resharper.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Postanowiłam sprawdzić na własnej skórze. Resharper ze względu na reklamę środowiskową oraz CodeRush ze względu na używanie DevExpressowych kontrolek. &lt;br/&gt;
Pobrały się wersje demo, zainstalowały. Być może to są fajne narzędzia, z wszelkich prezentacji można się dowiedzieć o ich tysiącu możliwości ... Ale nie oszukujmy się narzędzia nie są darmowe a ilość opcji powoduje że większość czasu w którym demo jest aktywne trzeba by poświęcić na zapoznanie się ze skrótami.&lt;br/&gt;
W dodatku VS2010 też wprowadza pod tym względem troszkę udogodnień jak moje ulubione wyszukiwanie po wielbłądzich garbach.&lt;br/&gt;
Projekt zarzuciłam.
&lt;br/&gt;
Ostatnio jednak wpadłam przypadkiem na telerikową betę JustCode. Bety są darmowe ;)
&lt;br/&gt;&lt;br/&gt;
Być może nie jest to mega rozbudowane narzędzie - ale dlatego odrzuciłam poprzednie. Opcji nie ma wiele: wielbłądzie wyszukiwanie, zaznaczanie użyć zmiennej, skakanie (moje ulubione ostatnio skakanie interfejs - implementacja). &lt;br/&gt;
Jak na bete narzędzie jest całkiem sprytne, jak do tej pory jeszcze się nie pomyliło znajdując za to błędny np niezamkniętych znaczników html w projekcie ASP. Przy okazji nie jest aż tak pamięciożerne a i nie zakłóca zwyczajnej pracy.&lt;br/&gt;
&lt;br/&gt;
Warto spojrzeć i tylko czekać aż telerik zrobi jakaś fajną promocje powiązana z MSDN ;)
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/S4LmjkmxB1I/AAAAAAAAAIY/QZobvll_bX4/s1600-h/JustCode.bmp"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/S4LmjkmxB1I/AAAAAAAAAIY/QZobvll_bX4/s320/JustCode.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5441164798613063506" /&gt;&lt;/a&gt;


Update: z wersją 2010Q1 beta zmieniła się w wersje płatną. Coż biorąc pod uwagę to że firmy nie inwestują w takie narzędzia bo i po co 200$ jest poza zasięgiem, szczególnie biorąc pod uwagę ceny resharpera. 
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8749050659606441157?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8749050659606441157/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8749050659606441157&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8749050659606441157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8749050659606441157'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/02/koder-na-wspomagaczach.html' title='Koder na wspomagaczach'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lJKm6y9ygyE/S4LmjkmxB1I/AAAAAAAAAIY/QZobvll_bX4/s72-c/JustCode.bmp' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8412312441435953909</id><published>2010-02-22T19:56:00.005+01:00</published><updated>2010-02-22T20:55:22.398+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Enum</title><content type='html'>&lt;b&gt;Bryczka z flagami  &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
    public enum Kolorki
    {
        None ,
        Black ,
        Red ,
        Green ,
        Blue 
    };
&lt;/pre&gt;
Koń jaki jest każdy widzi. A co jeśli byśmy chcieli mieć bryczkę z kiloma końmi?
&lt;br/&gt;
Pamięć przywiodła mi myśl o bitach, ale pomyślałam sobie - że niby nie ma czegoś nowszego i elegantszego?
&lt;pre name="code" class="brush:c-sharp;"&gt;
   [FlagsAttribute] 
    public enum Kolorki
    {
        None ,
        Black ,
        Red ,
        Green ,
        Blue 
    };
    //Kolorki.Green = Kolorki.Black | Kolorki.Red
&lt;/pre&gt;
Świetnie bryczka z flagami. Tylko że:&lt;br/&gt;
po wybraniu konika "zielonego" dostajemy - parę "czerwony, czarny", a to z powodu tego że możliwości ponumerują się po kolei.
&lt;br/&gt;
Więc wracam do opcji bitowej.
&lt;pre name="code" class="brush:c-sharp;"&gt;
  public enum Kolorki
    {
        None = 0,
        Black = 1,
        Red = 2,
        Green = 4,
        Blue = 8
    };
&lt;/pre&gt;
Świetnie zielony jest zielony. Ponieważ wartości na siebie nie nachodzą.&lt;br/&gt;
Jednak Black | Green daje ... 5
&lt;pre name="code" class="brush:c-sharp;"&gt;
   [FlagsAttribute] 
    public enum Kolorki
    {
        None = 0,
        Black = 1,
        Red = 2,
        CzarnoCzerwony = Black | Red,
        Green = 4,
        Blue = 8
    };&lt;/pre&gt;
Dopiero połączenie opcji daje pożądane od początku efekty, więcej nawet możemy sobie deklarować pośrednie wartości.
&lt;br/&gt;
Hmm no tak ale teraz trzeba jakoś się dostać do wartości w zmiennej, ponieważ zazwyczaj chcemy się dowiedzieć czy  coś jest konkretnego koloru. &lt;br/&gt;
Z odsieczą przychodzą operacje bitowe.
&lt;pre name="code" class="brush:c-sharp;"&gt;
public bool EnumVariableContains(Kolorki combined, Kolorki checking)
{
     return ((combined &amp; checking) == cheking);
}
&lt;/pre&gt;
Pozostaje kwiestia pozbycia się jednego ze złączonych kolorków:
&lt;pre name="code" class="brush:c-sharp;"&gt;
 private void SomeSome()
{
   Kolorki c = Kolorki.Green | Kolorki.Red;
   //nie chcemy czerwonych
   c = c &amp; ~Kolorki.Red
}
&lt;/pre&gt;
Na zakończenie link to malej dyskusji 
&lt;a href="http://stackoverflow.com/questions/93744/most-common-c-bitwise-operations"&gt;StackOverFlow&lt;/a&gt; i innego posta gdzie łądnie narysowano bitki ;) &lt;a href="http://weblogs.asp.net/wim/archive/2004/04/07/109095.aspx"&gt;Wimdows.Net&lt;/a&gt;
&lt;br/&gt;
&lt;!-- No i jeszcze warto żeby zacząć od none, bądź od 1 lub 2 żeby się nie wkopać gdzieś w zero--&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8412312441435953909?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8412312441435953909/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8412312441435953909&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8412312441435953909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8412312441435953909'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2010/02/enum.html' title='Enum'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-7936776508114243113</id><published>2009-09-17T21:03:00.010+02:00</published><updated>2009-09-17T22:35:40.038+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><title type='text'>nHibernate associations introduction</title><content type='html'>&lt;b&gt;Mapowanie relacji pomiędzy tabelami na asocjacje klas to dusza ORMow.  &lt;/b&gt;&lt;br/&gt;
To przy okazji najbardziej problematyczne zagadnienie.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Zagadnienie relacji jest szerokie jak rzeka i nie sposób opisać wszystkich przypadków. Najważniejsze z mojego punktu widzenia jest jednak zrozumieć sedno sprawy, zrozumienia tego brakowało przy moich pierwszych próbach i przyznam że zjadło mi to wiele godzin.&lt;br/&gt;
&lt;br/&gt;
Dzięki zastosowaniu klas POCO możemy posługiwać się niedostępnymi dla modelu DataSetów kolekcjami i powiązaniami między nimi. Musimy jednak pamiętać o tym że:
&lt;br/&gt;
&lt;b&gt;asocjacje w nHibernate są z natury &lt;span style="color:purple;"&gt; skierowane jednokierunkowe.&lt;/span&gt;&lt;/b&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SrKQf8SU2HI/AAAAAAAAAHg/N2mMj-bRNJs/s1600-h/bez%C2%A0tytu%C5%82u1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 269px; height: 26px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SrKQf8SU2HI/AAAAAAAAAHg/N2mMj-bRNJs/s320/bez%C2%A0tytu%C5%82u1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5382523383094499442" /&gt;&lt;/a&gt;
Powiązanie powyższych klas to dla nHibernate dwa zupełnie osobne powiązania Bid -&gt; Item  oraz Item -&gt; Bid.&lt;br/&gt; 
To dalej oznacza że przypisania &lt;span style="font-weight:bold; font-family: Courier New;"&gt;bid.Item = item&lt;/span&gt; oraz &lt;span style="font-weight:bold; font-family: Courier New;"&gt;item.Bids.Add(bid)&lt;/span&gt; to &lt;b&gt; dwie oddzielne operacje.&lt;/b&gt;
&lt;br/&gt;&lt;br/&gt;
Modelując powyższe klasy będziemy mieli taki oto przykład. &lt;br/&gt;
Na początek proste jednokierunkowe powiązanie&lt;span style="font-weight:bold;font-style:italic;"&gt;many-to-one&lt;/span&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
public class Bid 
{
  ...
  private Item item;
  public Item Item 
  {
    get { return item; }
    set { item = value; }
  }
...
}
&lt;/pre&gt;
Oraz plik XML
&lt;pre name="code" class="brush:xml;"&gt;
&lt;class name="Bid" table="BID"&gt;
  ...
  &lt;many-to-one name="Item" column="ITEM_ID"
    class="Item" not-null="true" /&gt;
&lt;/class&gt;
&lt;/pre&gt;
Kolumna ITEM_ID tabeli BID jest kluczem obcym do klucza głównego tabeli ITEM.&lt;br/&gt;
&lt;br/&gt;
Do czasu kiedy powiązania pozostają jedno -kierunkowe bardzo prosto korzysta się z nHibernata nie zdając sobie nawet sprawy z tego co może się dziać gdzie głębiej.&lt;br/&gt;
Ale czy nie było by użytecznym mieć również powiązanie w drugą stronę? Oj było by, a w aplikacjach opartych na czysto microsoftowych kontrolkach aspowych nie wyobrażam sobie żeby można było nie mieć dwukierunkowych powiązań.&lt;br/&gt;&lt;br/&gt;
Tak więc stwórzmy powiązanie w drugą stronę &lt;span style="font-weight:bold;font-style:italic;"&gt;one-to-many.&lt;/span&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
public class Item 
{
  ...
  private ISet bids = new HashedSet();
  public ISet Bids {
    get { return bids; }
    set { bids = value; }
  }
  public void AddBid(Bid bid) 
  {
    bid.Item = this;
    bids.Add(bid);
  }
...
}
&lt;/pre&gt;
&lt;pre name="code" class="brush:xml;"&gt;
&lt;class name="Item" table="ITEM"&gt;
...
  &lt;set name="Bids"&gt;
    &lt;key column="ITEM_ID"/&gt;
    &lt;one-to-many class="Bid"/&gt;
  &lt;/set&gt;
&lt;/class&gt;
&lt;/pre&gt;
Mapowanie kolumny określone elementem &lt;b&gt;&lt;key&gt;&lt;/b&gt; jest to kolumna klucza obcego w tabeli BID.&lt;br/&gt;
Dla obu asocjacji została określona ta sama kolumna klucza obcego.&lt;br/&gt;
Teraz mamy dwie różne jednokierunkowe acjocjacje do tego samego klucza obcego.&lt;br/&gt;
I to jest oczywiście problem jeśli spróbujemy zrobić jakąś operację zapewne dostaniemy błąd z serii "Próba modyfikacji obiektu przypisanego do innej sesji". Wynika to z faktu że mając dwie różne asocjacje mamy dwie różne reprezentacje tej samej wartości klucza w pamięci - a co za tym idzie dwie różne zmiany i konflikt.&lt;br/&gt;

&lt;b&gt;nHibernate sam z siebie NIE wykrywa faktu że te dwie zmiany dotyczą tej samej kolumny w bazie danych.&lt;/b&gt; Musimy powiedzieć nHibernatowi że te dwa powiązania jednokierunkowe to jedno powiązanie dwukierunkowe. A wystarczy do tego atrybut INVERSE
&lt;pre name="code" class="brush:xml;"&gt;
&lt;class name="Item" table="ITEM"&gt;
...
  &lt;set name="bids" inverse="true"&gt;
    &lt;key column="ITEM_ID"/&gt;
    &lt;one-to-many class="Bid"/&gt;
  &lt;/set&gt;
&lt;/class&gt;
&lt;/pre&gt;
Deklarując atrybut INVERS="true" (domyślnie oczywiście false) wyraźnie wskazujemy która końcówka tej asocjacji ma być synchronizowana z bazą danych. W tym przypadku mówimy że do bazy propagowane mają być zmiany w obiekcie Item natomiast zmiany w kolekcji bids mają być ignorowane. Zapis item.Bids.Add(bid) nie będzie miał żadnego efektu w składnicy danych, ponieważ domyślną wartością kolejnego atrybutu jest "none" (chyba że wywołamy sobie na tym obiekcie ISession.Save()).
&lt;pre name="code" class="brush:xml;"&gt;
  &lt;class name="Item" table="ITEM"&gt;
...
  &lt;set name="Bids" inverse="true" cascade="save-update"&gt;
     &lt;key column="ITEM_ID"/&gt;
     &lt;one-to-many class="Bid"/&gt;
   &lt;/set&gt;
&lt;/class&gt;
&lt;/pre&gt;
Aby zmiany dokonane w Bids były propagowane do bazy musimy ustawić atrybut CASCADE="save-update" (możliwe jest również "all-delete-orphan" przydatne przy relacjach parent-child).&lt;br/&gt;
Atrybut CASCADE mówi nHibernatowi aby zapisał do bazy każdy nowy obiekt Bid jeśli Bid jest 'składnikiem' Item.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-7936776508114243113?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/7936776508114243113/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=7936776508114243113&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7936776508114243113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7936776508114243113'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/09/nhibernate-associations-introduction.html' title='nHibernate associations introduction'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lJKm6y9ygyE/SrKQf8SU2HI/AAAAAAAAAHg/N2mMj-bRNJs/s72-c/bez%C2%A0tytu%C5%82u1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-9163934215191750249</id><published>2009-09-16T21:00:00.004+02:00</published><updated>2009-09-16T21:35:10.020+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><title type='text'>Definiowania meta danych mapowania</title><content type='html'>Lepiej będzie tu zawrzeć orginalną definicje metadanych&lt;br/&gt;
&lt;b&gt;  ORM &lt;/b&gt; tools require a metadata format for the application to specify the mapping between classes and tables,
properties and columns, associations and foreign keys, .NET types and SQL types. This information is called
the object/relational mapping metadata. It defines the transformation between the different data type systems
and relationship representations.
&lt;br/&gt;
Omawiać będę tylko mapowanie poprzez XML (możliwe jest jeszcze mapowanie poprzez atrybuty) ponieważ jest ono stosowane w projekcie w którym pracuje.
&lt;br/&gt;
&lt;span class="fullpost"&gt;


Przykładowy xml mapowania – plik taki powinien mieć rozszerzenie hbm.xml czyli np. Category.hbm.xml oraz musi być włączony do projektu .net jako Embedded Resource 

&lt;pre name="code" class="brush:xml;"&gt;
&lt;?xml version="1.0"?&gt;
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"&gt;
&lt;class name="CaveatEmptor.Model.Category, CaveatEmptor" lazy="false"&gt;
&lt;id name="Id"&gt; 
&lt;generator class="native" /&gt;
&lt;/id&gt;
&lt;property name="Name" column="name"/&gt;
&lt;many-to-one name="ParentCategory" cascade="all"/&gt;
&lt;/class&gt;
&lt;/hibernate-mapping&gt;
&lt;/pre&gt;
Property mapping&lt;br/&gt;
Mapowanie property zazwyczaj zawiera nazwę property, nazwę kolumny w bazie danych i może mieć jeszcze kilka innych atrybutów, jednak nie są one już konieczne. Zalecane jest stosowanie not-null w celu walidacji danych przed wysłaniem do bazy. Typ określany jest na podstawie typu property za pomocą reflection – jeśli nie zostanie podany.
&lt;br/&gt;
Przykładowe mapowanie propercji:
&lt;pre name="code" class="brush:xml;"&gt;
&lt;property name="InitialPrice" column="INITIAL_PRICE" not-null="true"/&gt;
&lt;/pre&gt;
Oczywiście jest wiele dalszych możliwości jednak w większości przypadków proste propercje są wystarczające, przynajmniej narazie ;)
&lt;br/&gt;
&lt;br/&gt;
Możemy sterować zapisem danej propercji do bazy
&lt;pre name="code" class="brush:xml;"&gt;
&lt;property name="Name" column="NAME" type="String" insert="false" update="false"/&gt;
&lt;/pre&gt;
Powyższa property nie zostanie nigdy zmodyfikowana w bazie (nie pojawi się ani w Insercie ani w Updacie)
&lt;br/&gt;
&lt;br/&gt;
Być może przydatnym może okazać się poniższe porównanie.
&lt;pre name="code" class="brush:xml;"&gt;
&lt;?xml version="1.0"?&gt;
&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation="urn:nhibernate-mapping-2.2
http://nhibernate.sourceforge.net/schemas/nhibernate-mapping.xsd"&gt;
&lt;class
name="NHibernate.Auction.Model.User, NHibernate.Auction"&gt;
...
&lt;/class&gt;
&lt;/hibernate-mapping&gt;

=====

&lt;hibernate-mapping
namespace="NHibernate.Auction.Model"
assembly="NHibernate.Auction"&gt;
&lt;class
name="User"&gt;
...
&lt;/class&gt;
&lt;/hibernate-mapping&gt;
&lt;/pre&gt;

Czyli możemy sobie zadeklarować domyślny assembly i namespace dla klasy lub powtarzać pełną nazwę za każdym razem.
&lt;br/&gt;
Kolejnym krokiem są asocjacje
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-9163934215191750249?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/9163934215191750249/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=9163934215191750249&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9163934215191750249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9163934215191750249'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/09/definiowania-meta-danych-mapowania.html' title='Definiowania meta danych mapowania'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-1338225586511170451</id><published>2009-09-16T20:18:00.008+02:00</published><updated>2009-09-16T21:14:42.115+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nHibernate'/><title type='text'>POCO</title><content type='html'>Ostatnio wrzuci mnie w projekcik z którym z woli klienta dostęp do bazy realizowany jest z wykorzystaniem nHibernata&lt;/br&gt;
Troche więc o nHibernacie aby nie umkneło na przyszłość.&lt;br/&gt;
Na początek&lt;br/&gt;
&lt;b&gt;POCO = Plain Old CLR Object&lt;/b&gt;&lt;br/&gt;
Czyli proste niezwiązane klasy zawierające zazwyczaj proste property. &lt;br/&gt;
NHibernate nie wymaga nawet aby klasa była serializowalna wymaga jedynie domyślnego bezparametrowego konstruktora oraz publicznych property wyrażających asocjacje między klasami POCO.
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Klasy POCO są reprezentacją modelu fizycznego, trzeba przestrzegać kilka zasad, rozważmy więc poniższy przykład.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SrExOR60m8I/AAAAAAAAAHY/rnYTgblFXCw/s1600-h/bez%C2%A0tytu%C5%82u.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 183px; height: 76px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SrExOR60m8I/AAAAAAAAAHY/rnYTgblFXCw/s320/bez%C2%A0tytu%C5%82u.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5382137151082503106" /&gt;&lt;/a&gt;

To asocjacja jeden-do-wiele a przypadkiem jeszcze do siebie samego.
&lt;pre name="code" class="brush:c-sharp;"&gt;
public class Category : ISerializable 
{
   private string name;
   private Category parentCategory;
   private ISet childCategories = new HashedSet();
   public Category() { }
   ...
}
&lt;/pre&gt;
Aby zaimplementować powiązanie potrzebujemy dwóch atrybutów parentCategory implementujące końcówkę‘jeden’ połączenia oraz childCategories – atrybut kolekcja implementujący końcówkę ‘wiele’.
&lt;pre name="code" class="brush:c-sharp;"&gt;
public ISet ChildCategories 
{
   get { return childCategories; }
   set { childCategories = value; }
}
public Category ParentCategory 
{
   get { return parentCategory; }
   set { parentCategory = value; }
}
&lt;/pre&gt;
Dodawanie childa Categoty wyglądała by tak
&lt;pre name="code" class="brush:c-sharp;"&gt;
Category aParent = new Category();
Category aChild = new Category();
aChild.ParentCategory = aParent;
aParent.ChildCategories.Add(aChild);
&lt;/pre&gt;
Dobrze jest systematyzować takie dodawanie połączeń w procedury z wiadomych powodów
&lt;pre name="code" class="brush:c-sharp;"&gt;
public void AddChildCategory(Category childCategory) {
if (childCategory.ParentCategory != null)
childCategory.ParentCategory.ChildCategories
.Remove(childCategory);
childCategory.ParentCategory = this;
childCategories.Add(childCategory);
}
&lt;/pre&gt;
Zawsze w takim przypadku muszą być wykonane dwie akcje:&lt;/br&gt;
- property parent musi zostać ustawione dla obiektu child&lt;/br&gt;
- obiekt child musi zostać dodany do kolekcji childów parenta.
&lt;/br&gt;&lt;/br&gt;
Wynika to z faktu że NHibernate nie zarządza sam z siebie asocjacjami więc jeśli chcemy stworzyć lub zmienić jakąś asocjacje to należy zrobić tyle ile byśmy zrobili bez NHibernata. &lt;b&gt;Obiekt powinien być tak napisany aby przechodzić testy jednostkowe, więc wszystkie asocjacje muszą zostać przypisane na poziomie obiektu.&lt;/b&gt;
Jeśli asocjacja jest dwukierunkowa oba kierunki muszą zostać uzupełnione.
&lt;/br&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-1338225586511170451?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/1338225586511170451/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=1338225586511170451&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1338225586511170451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/1338225586511170451'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/09/poco.html' title='POCO'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/SrExOR60m8I/AAAAAAAAAHY/rnYTgblFXCw/s72-c/bez%C2%A0tytu%C5%82u.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3415236984923154324</id><published>2009-06-22T00:47:00.006+02:00</published><updated>2009-06-22T01:17:22.731+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC - V jak Widok - Edycja, podgląd, dodawanie</title><content type='html'>&lt;b&gt; Widok - edycja oraz dodawanie &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Oprócz opisanych wcześniej list musimy jeszcze operować na poszczególnych rekordach. Mamy do dyspozycji Create, Details, Edit z standardowych templatów.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-OAdKUQI/AAAAAAAAAGI/X9adhbctu7c/s1600-h/2.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 347px; height: 374px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-OAdKUQI/AAAAAAAAAGI/X9adhbctu7c/s400/2.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342463468329652482" /&gt;&lt;/a&gt;
O ile dla &lt;b&gt;Details&lt;/b&gt; czyli podglądu sprawa jest prosta to dla pozostałych akcji standardowo generowane są dwie metody. Jedna odpowiedzialna na wysyłanie danych do widoku &lt;b&gt;GET&lt;/b&gt;, druga odpowiedzialna za przetwarzanie danych zwróconych przez widok &lt;b&gt;POST&lt;/b&gt;.&lt;/br&gt;
Dla podglądu oczywiście wystarczy dostarczyć dane które mają być prezentowane (tylko GET).&lt;br/&gt;&lt;br/&gt;
Dla &lt;b&gt;Create&lt;/b&gt; czyli dodania nowego rekordu w metodzie Get powinniśmy zapewnić niezbędne dane pomocnicze jak zawartość list rozwijalnych, czy jakieś tytuły opisy.&lt;br/&gt;
Natomiast w metodzie POST dostaniemy nowo utworzony obiekt, który zapewne należało by wysłać do bazy danych aby nie zginął.&lt;br/&gt;
W metodzie POST jako parametr widnieje obiekt Risk bo dla takiego stworzyłam sobie ten widok, widoczna wcześniej składnia "[Bind(Exclude="RiskID")]" oznacza że nie potrzebujemy ID, ono nam się gdzieś indziej z automatu utworzy.
&lt;pre name="code" class="brush:c-sharp;"&gt;
   public ActionResult Preview(int? id)
   {
        ViewData["title"] = "Edycja ryzyka";   
        var riskToEdit = (from m in edul.Risks
                          where m.RiskID == id
                          select m).First();
        //wyciagniecie z bazy rekordu dla wskazanego id

        return View(riskToEdit);
    }


        // GET: 
    public ActionResult Create()
    {
        ViewData["ddl"] = new SelectList(edul.RiskTypes.ToList(),"RiskTypeID","RiskTypeCode");
        // przekazanie zrodla danych do ddl
        return View();
    }

        //
        // POST: /Risk/Create
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude="RiskID")]NPEduLinqDataAccess.Risk riskToInsert )
    {
        try
        {
            if (!ModelState.IsValid)
                return View();
            
            edul.Risks.InsertOnSubmit(riskToInsert); 
            edul.SubmitChanges(); //zapisanie dodanego rekordu do bazy danych
                               
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }
&lt;/pre&gt;
&lt;b&gt;Edit&lt;/b&gt;. Edycja jest połączeniem podglądu i dodania. W metodzie Get musimy zapewnić nie tylko dane pomocnicze do list, ale rónież rekord który ma być edytowany, natomiast gdy wraca do nas zmodyfikowany rekord w metodzie POST musimy się nim zająć i zapisać go do bazy. &lt;br/&gt; 
W poniższym przykładzie wykorzystany jest model danych LinqToSql dla którego nie znalazłam metody która aktualizowała by pola orginalnego rekordu, w EntityFramework wywołalibyśmy jedną metodę zamiast zmieniać wszystkie property po kolei (być może jest lepsze rozwiązanie jednak ja zbytnio go nie szukałam).
&lt;pre name="code" class="brush:c-sharp;"&gt;
    // GET: /Risk/Edit/5

    public ActionResult Edit(int id)
    {
        ViewData["title"] = "Edycja ryzyka";
        ViewData["ddl"] = new SelectList(edul.RiskTypes.ToList(), "RiskTypeID", "RiskTypeCode"); //zrodlo danych dla DDL
        var riskToEdit = (from m in edul.Risks
                           where m.RiskID == id
                           select m).First();
                           //rekord o przekazanym id do wyswietlenia

        return View(riskToEdit);
    }

    //
    // POST: /Risk/Edit/5

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, NPEduLinqDataAccess.Risk riskToEdit)
    {
        try
        {
            var originalRisk =  edul.Risks.First(x =&gt;x.RiskID == riskToEdit.RiskID);
            //pobranie orginalnego rekordu przed edycja                                  

            if (!ModelState.IsValid)
                return View(originalRisk );

                
            originalRisk.RiskCode  = riskToEdit.RiskCode;
            originalRisk.RiskDesc = riskToEdit.RiskDesc;
            originalRisk.RiskTypeID  = riskToEdit.RiskTypeID;
            //aktualnizacja danych
            edul.SubmitChanges ();//zapisanie zmodyfikowanego rekordu do bazy 

            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }
&lt;/pre&gt;
Testując różne konfiguracje warstwy dostępu do danych okazało się że w przypadku typowanych DataSetów pojawia się problem. Metoda POST wymaga domyślnego konstruktora dla obiektu, natomiast wiersz z takiego DataSeta niestety bezparametrowego konstruktora nie posiada. &lt;br/&gt;
Nadal możemy korzystać z DataSetów jako źródła danych dla widoków MVC jednak stracimy silne typowanie ponieważ jako obiekt zwracany najlepiej będzie nam użyć typu &lt;span style="color:blue"&gt; FormCollection&lt;/span&gt;, w którym odnosimy się do kolekcji poprzez nazwy pól w modelu (nazwy pól w wierszu z dataSeta). Poniżej pokomplikowany przykład z DataSetem
&lt;pre name="code" class="brush:c-sharp;"&gt;
        //
        // GET: /Policy/Create

        public ActionResult Create()
        {
            var variant = from c in edul.Variants
                          select new { id = c.VariantID, text = string.Format("{0}, {1}", c.VariantCode, c.VariantDesc) };
            ViewData["ddl"] = new SelectList(variant.ToList(), "id", "text");

            return View();
        }

        //
        // POST: /Policy/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(FormCollection collection)
        {
//NPEduBaseObjects.Policy.PolicyDS.PolicyRow newPolicy)  czyli po typie NPEduBaseObjects.Policy.PolicyDS+PolicyRow
//-&gt; zwraca blad Dla tego obiektu nie zdefiniowano konstruktora bez parametrˇw.
            try
            {

                //wyciagniecie period
                var period = (from c in edul.VariantPeriods
                              where c.Variant.VariantID == System.Convert.ToInt32(collection["PolicyVariantID"])
                              select c.VariantPeriodID).Max();

                NPEduServerObjects.Policy.Policy pol = new NPEduServerObjects.Policy.Policy();
                NPEduBaseObjects.Policy.PolicyDS.PolicyRow newPolicy = pol.BeginAddPolicy(
                    System.Convert.ToDateTime(collection["PolicyDate"]),
                    System.Convert.ToDateTime(collection["PolicyEndDate"]),
                    System.Convert.ToInt32(collection["PolicyInsuranceSumAmount"]),
                    System.Convert.ToDateTime(collection["PolicyStartDate"]),
                    System.Convert.ToInt32(collection["PolicyTotalFee"]),
                    System.Convert.ToInt32(collection["PolicyVariantID"]), period);
//bez walidacji - jesli mamy tutaj puste stringi - najprawdopodobniej dostaniemy bledy!! 
                
               
                pol.Update();

                return RedirectToAction("Index");
            }
            catch (Exception e)
            {
                return View();
            }
        }

&lt;/pre&gt;
Tak naprawdę wszystko powyżej odnosiło się tylko i wyłącznie do kontrolera. A jak to wygląda od strony wygenerowanego widoku? Bardzo prosto. &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper_members.aspx"&gt;System.Web.MVC.HtmlHelper&lt;/a&gt; udostępnia nam garstkę metod generujących TextBox, DropDownList, CheckBox, ListBox, RadioButton, TextArea i ValidationMessage. &lt;br/&gt;
Z tej niewielkiej ilości standardowych elementów można stworzyć w miarę funkcjonalną stronę. Oczywiście możemy napisać swoje metody rozszerzające gamę generowanych elementów. &lt;br/&gt;
Przyznam że nie przetestowałam wszystkich elementów, zatrzymałam się na chwile nad DropDownList. W wyżej prezentowanych przykładach wysyłam sobie dane do takiej listy sformatowane do typu &lt;span style="color:blue"&gt;SelectListItem &lt;/span&gt;. Metoda Html.DropDownList przyjmuje dwa parametry, według opisu "name" czyli "The name of the form field" i "selectList".&lt;br/&gt;
I tutaj wielkie fiasko myślenia WebForms. Name nie jest nazwą kontrolki. Myśląc logicznie po pewnym czasie dochodzi się do wniosku że przecież tu nie ma kontrolki bo właśnie generujemy kod HTML, jednak odruchy pozostają.&lt;br/&gt;
Koniec końców okazuje się że Name jest to nazwa pola z obowiązującego modelu, do którego wybrana z DDL wartość ma być podbindowana.
&lt;pre name="code" class="brush:html;"&gt;
&lt; %@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;NPEduLinqDataAccess.Risk&gt;" %&gt;
&lt; %@ Import  Namespace="MvcContrib.Binders" %&gt;
&lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
 Create
&lt;/asp:Content&gt;

&lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;

    &lt;h2&gt;Create&lt;/h2&gt;

    &lt; %= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") % &gt;

    &lt; % using (Html.BeginForm()) { % &gt;

        &lt;fieldset&gt;
            &lt;legend&gt;Fields&lt;/legend&gt;
            &lt;p&gt;
                &lt; label for="RiskCode"&gt;RiskCode:&lt;/label&gt;
                &lt; %= Html.TextBox("RiskCode") %&gt;
                &lt; %= Html.ValidationMessage("RiskCode", "*") %&gt;
            &lt;/p&gt;
            &lt;p&gt;
                &lt; label for="RiskDesc"&gt;RiskDesc:&lt;/label&gt;
                &lt; %= Html.TextBox("RiskDesc") %&gt;
                &lt; %= Html.ValidationMessage("RiskDesc", "*") %&gt;
            &lt;/p&gt;
            &lt;p&gt;
                &lt; label for="RiskTypeID"&gt;RiskType:&lt;/label&gt;
                &lt; %= Html.DropDownList("RiskTypeID", ViewData["ddl"] as SelectList)%&gt;
            &lt; %-- 
                &lt; %= Html.TextBox("RiskTypeID") %&gt;
                &lt; %= Html.ValidationMessage("RiskTypeID", "*") %&gt;
            --% &gt;
            &lt;/p&gt;
            &lt;p&gt;
                &lt;input type="submit" value="Create" /&gt;
            &lt;/p&gt;
        &lt;/fieldset&gt;

    &lt; % } % &gt;

    &lt;div&gt;
        &lt; %=Html.ActionLink("Back to List", "Index") %&gt;
    &lt;/div&gt;

&lt;/asp:Content&gt;

&lt;/pre&gt;

&lt;br/&gt;
O samym widoku nie ma wiele więcej do powiedzenia z wyjątkiem walidacji (tutaj bym rzuciła hasłem xVal ale nie sprawdzałam sprawy).
&lt;br/&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3415236984923154324?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3415236984923154324/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3415236984923154324&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3415236984923154324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3415236984923154324'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/06/mvc-v-jak-widok-edycja-podglad.html' title='MVC - V jak Widok - Edycja, podgląd, dodawanie'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-OAdKUQI/AAAAAAAAAGI/X9adhbctu7c/s72-c/2.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-7163659085795016219</id><published>2009-06-04T22:22:00.002+02:00</published><updated>2009-06-04T22:50:18.539+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>C# ?? null Coalescing operator</title><content type='html'>&lt;b&gt;C# ?? null Coalescing operator  &lt;/b&gt;
&lt;br/&gt;
Ha nigdy nie mogę tego słówka zapamiętać jak w nim oa i inne samogłoski idą.&lt;br/&gt;
Może to odgrzewane kotlety ale dziś przy okazji okazji znalazłam opis takiego operatora - oczywiście na &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx"&gt; blogu Scotta Gu&lt;/a&gt;&lt;/br&gt;

&lt;span class="fullpost"&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
    int? number = 10;
    int nu = number.HasValue ? number : 0 ;
&lt;/pre&gt;
Ale przecież nie o tym mowa. &lt;br/&gt;
Jednak mowa o tym jak można powyższe zastąpić.

&lt;pre name="code" class="brush:c-sharp;"&gt;
    int? number = 50;
    int res = number ?? 0 ;
    //outcome: res ==55

    int? numberNull = null;
    res = numberNull ?? 0 ;
    //outcome: res ==0    
&lt;/pre&gt;
&lt;br/&gt;
W skrócie mówiąc operator &lt;b&gt;??&lt;/b&gt; sprawdza czy wartość po jego lewej stronie jest null'em, jeśli tak - to zwraca alternatywna wartość którą przedstawiamy po jego prawej stronie. Jeśli wartość przedstawiona po lewej zostanie zwrócona przez operator &lt;b&gt;??&lt;/b&gt; jeśli nie będzie ona null'owa
&lt;br/&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
     Customer cust = getCustomer(id) ?? new Customer();
    // znacznie przydatniejsze niz poniższe którego raczej nie wykorzystamy
     Customer cust = ( null == getCustomer(id) ) ? getCustomer(id) : new Customer();

    // i jeszcze miły przykład z ViewStatem
public string Title
{
  get { return (string)ViewState["title"] ?? "Default title"; }
  set { ViewState["title"] = value; }
}
&lt;/pre&gt;

&lt;br/&gt;
Ciekawym przykładem jest też użycie tego operatora do zapytań LINQ - przykład zaprezentowany na wyżej wymienionym blogu. Dzięki operatorowi ?? możemy nadać wartość domyślna elementowi zwracanemu z zapytania LINQ.
&lt;br/&gt;
&lt;br/&gt;
Cool
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-7163659085795016219?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/7163659085795016219/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=7163659085795016219&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7163659085795016219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/7163659085795016219'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/06/c-null-coalescing-operator.html' title='C# ?? null Coalescing operator'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-4164758068151324737</id><published>2009-06-01T22:31:00.028+02:00</published><updated>2009-06-21T20:50:47.500+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC - V jak Widok - Listy</title><content type='html'>&lt;b&gt;Widok - index czyli lista &lt;/b&gt;
&lt;br/&gt;
Widok z samego założenia wzorca projektowego jest zależny od kontrolera, po kolei będą więc przedstawiane przykłady i spostrzeżenia odnośnie obu.&lt;br/&gt;
Ponieważ wszystkiego jest dość dużo dlatego podział na listy i edycje.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;span class="fullpost"&gt;
Widok jest zawsze generowany na podstawie akcji kontrolera. &lt;br/&gt;
Wybierając w kontrolerze menu podręczne na jakiejś akcji widzimy opcje &lt;span style="font-style:italic;"&gt;Add View..&lt;/span&gt; i &lt;span style="font-style:italic;"&gt;Go to View&lt;/span&gt;. &lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiQ90oVybjI/AAAAAAAAAGA/vvWrpjXTmm8/s1600-h/1.gif"&gt;&lt;img style="display:block; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 186px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiQ90oVybjI/AAAAAAAAAGA/vvWrpjXTmm8/s400/1.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342463032359546418" /&gt;&lt;/a&gt;
Kolejne okno umożliwia wybór kilku podstawowych opcji jak nazwa widoku czy opcja &lt;span style="font-style:italic;"&gt;templatu &lt;/span&gt;widoku. &lt;br/&gt;
Jednak interesujące są te z listami rozwijalnymi. Pierwszy z nich &lt;span style="font-weight:bold;"&gt;Create a strongly-typed view&lt;/span&gt; umożliwia z listy rozwijalnej wybrać obiekt który będzie obowiązującym Modelem danego widoku.&lt;br/&gt;
Wyszukiwane są wszystkie rozpoznawalne typy równie dobrze mogą to być DataSety jak i obiekty Linq.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-SuzkKsI/AAAAAAAAAGQ/2eYP3KvEmnU/s1600-h/3.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 347px; height: 374px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-SuzkKsI/AAAAAAAAAGQ/2eYP3KvEmnU/s400/3.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342463549491129026" /&gt;&lt;/a&gt;

Druga lista &lt;span style="font-style:italic;"&gt;View content &lt;/span&gt;to template dla listy edycji czy dodawania.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-OAdKUQI/AAAAAAAAAGI/X9adhbctu7c/s1600-h/2.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 347px; height: 374px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SiQ-OAdKUQI/AAAAAAAAAGI/X9adhbctu7c/s400/2.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342463468329652482" /&gt;&lt;/a&gt;
&lt;br/&gt;
Piszemy więc pierwszą możliwie najprostszą listę. Wykorzystuję model LinqToSql.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 public ActionResult Index()
        {
            return View(context.Risks.OrderBy(x =&gt; x.RiskID).ToList());
        }
&lt;/pre&gt;
Generuje się widok którego model wskazuje na obiekt Linq &lt;span style="font-style:italic;"&gt;IEnumerable&lt;NPEduLinqDataAccess.Risk&gt;&lt;/span&gt;. Zastosowałam tutaj tylko jedną zmianę (opisaną w przykładzie) i widok jest w pełni funkcjonalny.&lt;br/&gt;&lt;br/&gt;
&lt;span style="font-style:italic; color:darkgrey;"&gt;Dygresja dotycząca wyświetlania: niestety nie znalazłam pędzla koloryzowania kodu dla ASP więc używam HTMLa, pewnie nie wygląda to pięknie ale liczy się treść.&lt;br/&gt;
Dygresja druga: &lt; %= oczywiście nie mogę połączyć &lt; i % ponieważ wtedy zostało by to zinterpretowane jako znacznik html więc będę używać spacji, mam nadzieje że nie zaciemni to kodu.&lt;br/&gt;&lt;br/&gt;
&lt;/span&gt;&lt; %= to taki sprytny znacznik który mówi to samo co Response.Write(). Ważny jest tutaj znak równości.
&lt;br/&gt;

&lt;pre name="code" class="brush:html;"&gt;
&lt; % @ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt; IEnumerable&lt; NPEduLinqDataAccess.Risk&gt;&gt;" %&gt;

&lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
    Index
&lt;/asp:Content&gt;
&lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
    &lt;h2&gt;
        Index&lt;/h2&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;/th&gt;
            &lt;th&gt;                RiskID            &lt;/th&gt;
            &lt;th&gt;                RiskCode          &lt;/th&gt;
            &lt;th&gt;                RiskDesc          &lt;/th&gt;
            &lt;th&gt;                RiskTypeCode      &lt;/th&gt;
            &lt;th&gt;                RiskTypeDesc      &lt;/th&gt;
        &lt;/tr&gt;
        &lt;% foreach (var item in Model)
           { %&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt; %= Html.ActionLink("Edit", "Edit", new { id=item.RiskID }) %&gt;&lt;/td&gt;
            &lt;td&gt;&lt; %= Html.Encode(item.RiskID) %&gt;&lt;/td&gt;
            &lt;td&gt;&lt; %= Html.Encode(item.RiskCode) %&gt;&lt;/td&gt;
            &lt;td&gt;&lt; %= Html.Encode(item.RiskDesc) %&gt;&lt;/td&gt;
            &lt;td&gt;
                &lt; %= Html.Encode(item.RiskType.RiskTypeCode) %&gt;
                &lt; %--RiskTypeID 
                    jedyna zmiana jaka tutaj stosuje to dodanie pol podrzednej tabelki
                    dzieki wykorzystaniu linq poprostu pisze kropke i to co chce dalej--%&gt;
            &lt;/td&gt;
            &lt;td&gt;&lt; %= Html.Encode(item.RiskType.RiskTypeDesc) %&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;% } %&gt;
    &lt;/table&gt;
    &lt;p&gt;
        &lt;%= Html.ActionLink("Create New", "Create") %&gt;
    &lt;/p&gt;
&lt;/asp:Content&gt;
&lt;/pre&gt;
To był obiekt Linq a teraz weźmy sobie DataSet
&lt;pre name="code" class="brush:c-sharp;"&gt;
  public ActionResult IndexFromSntFramework(int? id)
        {
            int pageSize = 10;
            NPEduServerObjects.Risk.RiskSearch riskSearch = new NPEduServerObjects.Risk.RiskSearch();

            riskSearch.GetRiskList((id.HasValue ? id.Value : 1), (pageSize * (id.HasValue ? id.Value : 0)));
            //wypełnianie tabelki search - odpowiadającej liście

            return View(riskSearch.DataSet.RiskSearch);
            //przekazujemy tabelkę silnie typowanego DataSeta
        }
&lt;/pre&gt;
Generujemy widok. Tworzy się widok z wpisem&lt;br/&gt;
&lt;span style="color:red;"&gt;Inherits&lt;/span&gt; &lt;span style="color:blue;"&gt;="System.Web.Mvc.ViewPage&lt; IEnumerable&lt; NPEduBaseObjects.Risk.RiskSearchDS+RiskSearchRow&gt;&gt;"&lt;/span&gt; &lt;br/&gt;- mapując Model widoku na wiersz naszej tabelki w DataSecie, reszta przebiega dokładnie tak samo jak powyżej. Do wyświetlania wystarcza jaknajbardziej.
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;

To duża siła - parę klików i mamy wygenerowany jakiś widok. &lt;br/&gt;
No właśnie jakiś widok.&lt;br/&gt;
Ale jeśli nie chcemy się dużo napisać... od razu człowiek zaczyna szukać gotowych rozwiązań. Na &lt;a href="http://www.codeplex.com/MVCContrib"&gt; CodePlex MvcContrib&lt;/a&gt; znajdujemy gotowe kontrolki w tym grida. &lt;br/&gt;
Metoda w C# jest niezwykle prosta, zawiera dodatkowo tylko parametr page a kontroler korzysta z biblioteki MvcContrib.Pagination.
&lt;pre name="code" class="brush:c-sharp;"&gt;
public ActionResult IndexAutoMagicznyGrid(int? page)
        {
            return View(edul.Risks.AsPagination(page.GetValueOrDefault(1), 10));
        }
&lt;/pre&gt;
Wygenerowany widok natomiast należy trochę zmodyfikować
&lt;pre name="code" class="brush:html;"&gt;
&lt; %@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt; IPagination&lt; NPEduLinqDataAccess.Risk&gt;&gt;" %&gt;
&lt; %@ Import Namespace="MvcContrib.UI.Pager"%&gt;
&lt; %@ Import Namespace="MvcContrib.UI.Grid"%&gt;
&lt; %@ Import Namespace="MvcContrib.Pagination"%&gt;

&lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
 AutoMagiczny Grid z inicjatywy MvcContrib
&lt;/asp:Content&gt;

&lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;

    &lt;h2&gt;IndexAutoMagicznyGrid&lt;/h2&gt;

    &lt; %= Html.Grid(Model).Columns(column =&gt; {
                column.For(x =&gt; x.RiskID).Named("Risk ID");
                column.For(x =&gt; x.RiskCode);
                column.For(x =&gt; x.RiskDesc);   
          }) %&gt;

     &lt;br /&gt;
     &lt; %= Html.Pager(Model) %&gt;
&lt;/asp:Content&gt;
&lt;/pre&gt;

Oto porównanie widoku standardowego grida oraz tego wygenerowanego przez Contrib. Contrib dostarcza od razu pagowanie (to ten co się nazywa AutoMagiczny :] ).
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiRKz8pt-BI/AAAAAAAAAGg/iXxlOdxiNxc/s1600-h/5.gif"&gt;&lt;img style="display:block; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 174px; height: 200px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiRKz8pt-BI/AAAAAAAAAGg/iXxlOdxiNxc/s200/5.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342477314283141138" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiRKv99lpcI/AAAAAAAAAGY/ClMd4EfL6m8/s1600-h/4.gif"&gt;&lt;img style="display:block; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 174px; height: 200px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SiRKv99lpcI/AAAAAAAAAGY/ClMd4EfL6m8/s200/4.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5342477245915440578" /&gt;&lt;/a&gt;
&lt;br/&gt;
Oczywiście możemy napisać swój kod generujący ślicznego grida ;)&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
Pozostała jeszcze jedna nie omówiona wcześniej opcja a mianowicie: &lt;span style="font-weight:bold;"&gt;Create a partial view&lt;/span&gt;. Jak sama nazwa wskazuje generowana jest tylko część widoku - template używany później w innym widoku. &lt;br/&gt;
Przykład ogranicza się do samego pliku widoku. Najpierw wygenerujmy template dla obiektu Risk:
&lt;pre name="code" class="brush:html;"&gt;
&lt; %@ Control Language="C#" Inherits="System.Web.Mvc.ViewPage&lt; IEnumerable&lt; NPEduLinqDataAccess.Risk&gt;&gt;" %&gt;
        &lt; tr&gt;
            &lt; td&gt;
                &lt; %= Html.ActionLink("Edit", "Edit", new { id=item.RiskID }) %&gt;
            &lt; /td&gt;
            &lt; td&gt;
                &lt; %= Html.Encode(item.RiskID) %&gt;
            &lt; /td&gt;
            &lt; td&gt;
                &lt; %= Html.Encode(item.RiskCode) %&gt;
            &lt; /td&gt;
            &lt; td&gt;
                &lt; %= Html.Encode(item.RiskDesc) %&gt;
            &lt; /td&gt;
            &lt; td&gt;
                &lt; %= Html.Encode(item.RiskType.RiskTypeCode) %&gt;
                &lt; %--RiskTypeID--%&gt;
            &lt; /td&gt;
            &lt; td&gt;
                &lt; %= Html.Encode(item.RiskType.RiskTypeDesc) %&gt;
            &lt; /td&gt;
        &lt; /tr&gt;
&lt;/pre&gt;
A teraz użyjmy templata w widoku listy
&lt;pre name="code" class="brush:html;"&gt;
&lt; %@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt; IEnumerable&lt; NPEduLinqDataAccess.Risk&gt;&gt;" %&gt;

&lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
 IndexPaged
&lt;/asp:Content&gt;

&lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;

    &lt;h2&gt;IndexPaged&lt;/h2&gt;

   &lt; table&gt;
        &lt; tr&gt;
            &lt; th&gt;            &lt;/ th&gt;
            &lt; th&gt;                RiskID            &lt; /th&gt;
            &lt; th&gt;                RiskCode          &lt; /th&gt;
            &lt; th&gt;                RiskDesc          &lt; /th&gt;
            &lt; th&gt;                RiskTypeCode      &lt; /th&gt;
            &lt; th&gt;                RiskTypeDesc      &lt; /th&gt;
        &lt; /tr&gt;
        &lt; % foreach (var item in Model)
           { %&gt;
            &lt; % Html.RenderPartial("IndexRowPart", item); %&gt; 
&lt;!-- tutaj podajemy nazwę pliku templatu zamiast definicji każdego pojedynczego wiersza--&gt;
        &lt; % } %&gt;
    &lt; /table&gt;
   
    &lt;p&gt;
        &lt; %= Html.ActionLink("Create New", "Create") %&gt;
    &lt;/p&gt;

&lt;/asp:Content&gt;
&lt;/pre&gt;


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-4164758068151324737?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/4164758068151324737/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=4164758068151324737&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4164758068151324737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/4164758068151324737'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/06/mvc-v-jak-widok-listy.html' title='MVC - V jak Widok - Listy'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lJKm6y9ygyE/SiQ90oVybjI/AAAAAAAAAGA/vvWrpjXTmm8/s72-c/1.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3245417580350234025</id><published>2009-05-30T20:53:00.012+02:00</published><updated>2009-05-30T22:12:57.168+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>CodeCamp</title><content type='html'>&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/SiGAyGyusDI/AAAAAAAAAFw/BNtL1Pq3h4U/s1600-h/codeCampLogo.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 137px; background-color:white;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/SiGAyGyusDI/AAAAAAAAAFw/BNtL1Pq3h4U/s400/codeCampLogo.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5341692231343321138" /&gt;&lt;/a&gt;
&lt;b&gt; CodeCamp Kraków  &lt;/b&gt; day 1 .NET 
&lt;br/&gt;
&lt;span class="fullpost"&gt;
6 sesji, 9 godzin, litr kawy i troche pizzy ;)&lt;br/&gt;

&lt;br/&gt;&lt;br/&gt;
09:15-10:30 Tadeusz Golonka i Marcin Książek - &lt;b&gt;Software Development Life Cycle z Team Foundation Server 2008&lt;/b&gt;&lt;br&gt;
Panowie przez przeszło godzinę opowiadali o TFSie widzianym okiem programisty i "nieprogramisity" project menadżera.&lt;br/&gt;
Używam TFS'a od roku, więc od strony programisty sądziłam że nic mnie nie zaskoczy, a jednak znalazło się kilka opcji które powędrowały na karteczkę z adnotacja - znajdź i użyj jak: Annotate, Shelve,Find changeset (niestety poprzez GetSpecificVersion ale i tak fajnie), bildy, statyczna analiza kodu (tu od razu dwa linki które warto by przejrzeć &lt;a href="http://blogs.msdn.com/fxcop/"&gt;fxCop&lt;/a&gt; &lt;a href="http://www.codeplex.com/TFSGuide"&gt;CodePlex TFS Guide&lt;/a&gt;) &lt;br/&gt;
Naprawdę szkoda że sesja nie trwała dłużej.
&lt;br/&gt;&lt;br/&gt;
10:45-11:45 Michał Brzozowski - &lt;span style="font-weight:bold;"&gt;Wprowadzenie do zasad SOLID&lt;/span&gt; &lt;br/&gt;
Michał mówił o tym jak kod staje się coraz trudniejszy w utrzymaniu i zrozumieniu (skomplikowanie kodu liczone w WTF/minute ;) ) oraz o zasadach SOLID mających przeciwdziałać temu zjawisku. Przewinął się również &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt; manifest&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;
12:00-13:00 Tomasz Kopacz - &lt;span style="font-weight:bold;"&gt;Programowanie równoległe i rozproszone w VS 2010&lt;/span&gt; &lt;br/&gt;
Tomek Kopacz jak zwykle przegalopował przez temat wykorzystania obecnie dostępnych procesorów oraz programowania równoległego w VS2010 zrywając widowni czapki z głów :]&lt;br/&gt;
VS2010 ma wiele elementów pozwalających szybko i prosto tworzyć aplikacje pracujące na wielu &lt;span style="font-style:italic;"&gt;Taskach&lt;/span&gt;, a debugger historyczny pomaga w sprawdzaniu aplikacji bo wie co to wątki
&lt;br/&gt;&lt;br/&gt;
14:00-15:00 Witold Bołt -&lt;span style="font-weight:bold;"&gt; Programowanie z głową w chmurach - wstęp do cloud computing i Windows Azure&lt;/span&gt;&lt;br/&gt;
Po przekąsce wszyscy przesunęliśmy głowy w chmury. Witek Bpłt opowiadał o Windows Azure i jego możliwościach a także drodze jaką musi pokonać request do chmury. Temat niezwykle ciekawy, jednak pizza jakoś przytłacza pamięć, warto powtórzyć tą sesje ;)&lt;br/&gt;&lt;br/&gt;
15:15-16:15 Marcin Najder - &lt;span style="font-weight:bold;"&gt;Workflow Foundation 4.0&lt;/span&gt;&lt;br/&gt;
Najważniejsza wiadomość: WF 4 jest zupełnie nowym rozwiązaniem w stosunku do 3. 3 nie da się zmigrować do 4 a trzeba ją przepisać. Wniosek stąd - warto zacząć w 4. A w 4 dalsze atrakcje jak XAML i bardzo dużo nowych aktywności... Może kiedyś i ten temat zgłębię ;) &lt;br/&gt;&lt;br/&gt;
&lt;span style="font-style:italic;"&gt;And the last but not the least:&lt;/span&gt;&lt;br/&gt;
16:30-17:45 Bartosz Kierun - &lt;span style="font-weight:bold;"&gt;Czy ASP.NET MVC oznacza zmierzch "klasycznego" ASP.NET?&lt;/span&gt; &lt;br/&gt;
Sesja na którą szczególnie czekałam ze względu mojego ostatniego zainteresowania MVC.&lt;br/&gt; Sesja bardzo fajna, choć o MVC powiedziane było głównie tyle - że na razie jest to technologia niedojrzała i warto zaczekać z implementacją. &lt;br/&gt;
Mam nadzieje że uda mi się napisać jeszcze jeden post na temat tej sesji z najważniejszymi punktami z niej wyniesionymi a było ich bardzo dużo i dotyczyły głównie nowości w ASP.NET 4 :)
&lt;!--&lt;pre name="code" class="brush:c-sharp;"&gt;
&lt;/pre&gt;--&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3245417580350234025?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3245417580350234025/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3245417580350234025&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3245417580350234025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3245417580350234025'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/codecamp.html' title='CodeCamp'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lJKm6y9ygyE/SiGAyGyusDI/AAAAAAAAAFw/BNtL1Pq3h4U/s72-c/codeCampLogo.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3289404334981930191</id><published>2009-05-28T23:48:00.015+02:00</published><updated>2009-05-29T12:24:36.960+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC Routing</title><content type='html'>&lt;b&gt;Gdzie ja jestem czyli Routing.  &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
W świecie ASP.NET URL odpowiadał namacalnemu plikowi.&lt;br/&gt;
W świecie MVC w którym posługujemy się pojęciami akcji i routingu URL nie ma nic wspólnego z plikiem, za to oczywiście ma wiele wspólnego z akcjami i kontrolerami.&lt;br/&gt;
&lt;!--&lt;span style="color:blue;font-name:courier"&gt;http://www.example.pl/{controller}/{action}/{id}&lt;/span&gt;&lt;br/&gt;--&gt;
&lt;br/&gt;
&lt;br/&gt;
A oto droga jaką pokonuje URL
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/Sh8Z2Uv66vI/AAAAAAAAAFg/YmM6ZHm6Fig/s1600-h/routies.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 90px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/Sh8Z2Uv66vI/AAAAAAAAAFg/YmM6ZHm6Fig/s400/routies.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5341016104158030578" /&gt;&lt;/a&gt;
&lt;br/&gt;
Routing URL zapewnia nam niezależność adresów od plików jest bardziej powiązany z logiką aplikacji, dobrze jest więc go prawidłowo zaprojektować. Warto zwrócić uwagę na takie zagadanienia:
&lt;ol&gt;
&lt;li&gt;utrzymywanie prostych i &lt;b&gt;krótkich&lt;/b&gt; adresów URL - łatwiejsze korzystanie z witryny dla użytkownika końcowego
&lt;li&gt;wprowadzenie wzorców umożliwiających pomijanie parametrów no events/&lt; rok&gt;/&lt; miesiac&gt;/&lt; data&gt;
&lt;li&gt;unikanie ujawniania ID z bazy a jeśli to jest konieczne - dodawanie zbędnych informacji w celu zwiększenia czytelności adresu
&lt;/ol&gt;

Przykładowe wzorce i pasujące do nich adresy zostały przedstawione w tabelce poniżej.
&lt;table style=""&gt;
&lt;tr&gt;&lt;td&gt;Wzorc Routingu &lt;/td&gt;&lt;td&gt;Przykładowy URL&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
{controller}/{action}/{id}&lt;br/&gt;
&lt;/td&gt;
&lt;td&gt;
/Products/Show/All
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
{controller}/{action}/{id}.aspx&lt;/td&gt;&lt;td&gt;/Products/Show/All.aspx&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
archive/{year}-{month}/{title}.aspx&lt;/td&gt;&lt;td&gt;/archive/2008-07/BlogPost.aspx&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
{language}-{country}/{controller}/
{action}/{id}&lt;/td&gt;&lt;td&gt;/en-us/Products/Show/All&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;
{department}/{title}.aspx&lt;/td&gt;&lt;td&gt;/Sales/Overview.aspx&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;br/&gt;


&lt;b&gt;Definiowanie Routingu&lt;/b&gt;&lt;br/&gt;
Routes są definiowane na starcie aplikacji czyli w &lt;span style="color:blue;"&gt;Global.asax &lt;/span&gt;w metodzie &lt;span style="color:blue;"&gt;Application_Start&lt;/span&gt;&lt;br/&gt;
&lt;br/&gt;
Używany jest zawsze pierwszy pasujący routing!&lt;br/&gt;
Jeśli nie pasuje - brany(sprawdzany) jest kolejny&lt;br/&gt;
Oprócz mapowania możemy użyć też Ignore aby pewne wzorce były pomijane - co przydaje się przy wykorzystywaniu równocześnie klasycznych stron ASP.NET.&lt;br/&gt;
Mapowanie przyjmuje do 4 parametrów (opisane w przykładowym kodzie).&lt;br/&gt;
Oto przykład pliku Global.asax
&lt;pre name="code" class="brush:c-sharp;"&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1
{
    public class GlobalApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            /* == 
            routes.Add(
            new Route("{resource}.axd/{*pathInfo}",
            new StopRouteHandler())
            );*/

            /*Force routing handler to process all of the .aspx requests 
              for the directory /Classsic int the regular ASP.NET way */
            routes.Add(
            new Route("Classic/{resource}.aspx?{*requestUrl}",
            new StopRoutingHandler())
            );
            routes.Add(
            new Route("Classic/{resource}.aspx",
            new StopRoutingHandler())
            );

            //---------- add route
            routes.MapRoute(
            "ProductShow", // Route name
            "Product/{id}-{title}.asp", // URL with parameters
            new
            { // Parameter defaults
                controller = "Product",
                action = "Show",
                id = "",
                title = ""
            },
            new { id = @"[\d.*]" } // Parameter constraints
            );
            routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new
            { // Parameter defaults
                controller = "Home",
                action = "Index",
                id = ""
            }
            );
        }
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}
&lt;/pre&gt;
Jeśli mamy określony parametr&lt;b&gt; id&lt;/b&gt; w routingu w funkcji będącej akcją musi nazywać się on tak samo.
&lt;pre name="code" class="brush:c-sharp;"&gt;
        public ActionResult Index()
        {
            //widok generowany z automatu       
            return View(edul.Risks.ToList());
        }

        public ActionResult IndexPaged(int? id) //parametr musi sie nazywac tak jak w routingu!!
        {
            int pageSize = 10;

            return View(edul.Risks.Skip(pageSize * (id.HasValue ? id.Value : 0)).Take(pageSize).ToList());
        }
&lt;/pre&gt;
Ostatni z parametrów wymusza restrykcje parametrów. Możliwe jest napisanie własnej funkcji definiujące takie restrykcje. Funkcja taka musi implementować interface &lt;span style="color:blue;"&gt;IRouteConstraint&lt;/span&gt;:

&lt;pre name="code" class="brush:c-sharp;"&gt;
public class AuthenticatedRouteConstraint : IRouteConstraint
{
    #region IRouteConstraint Members
    public bool Match(HttpContextBase httpContext, Route route,
    string parameterName, RouteValueDictionary values,
    RouteDirection routeDirection)
    {
        // Match only when user is authenticated
        return httpContext.Request.IsAuthenticated;
    }
    #endregion
}
&lt;/pre&gt;
Odpowiedni kawałek kodu w Global.asax
&lt;pre name="code" class="brush:c-sharp;"&gt;
routes.MapRoute(
        "Secret",
        "Secret/{action}",
        new { controller = "Secret", action = "Index" },
        new { authenticated = new AuthenticatedRouteConstraint() }
);
&lt;/pre&gt;
&lt;!-- mozliwe jest mapowanie namespasow ale nie bede tego narazie przerabiac --&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3289404334981930191?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3289404334981930191/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3289404334981930191&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3289404334981930191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3289404334981930191'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/mvc-routing.html' title='MVC Routing'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/Sh8Z2Uv66vI/AAAAAAAAAFg/YmM6ZHm6Fig/s72-c/routies.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2407387971961003620</id><published>2009-05-27T00:06:00.009+02:00</published><updated>2009-05-27T01:40:02.213+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><title type='text'>MVC - C jak kontroler</title><content type='html'>&lt;b&gt;  &lt;/b&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Każda metoda klasy kontrolera oznaczona jako public
jest automatycznie akcja i możliwe jest dostanie się to niej z dowolnego miejsca przez odpowiednie wysterowanie URLem.&lt;br/&gt;
&lt;br/&gt;
Aby metoda była akcją musi spełniać warunki:
&lt;ol&gt;
&lt;li&gt;musi być  &lt;span style="color:blue"&gt;public&lt;span&gt;
&lt;li&gt;nie może być  &lt;span style="color:blue"&gt;static&lt;span&gt;
&lt;li&gt;nie może być metodą rozszerzeń (extension method)
&lt;li&gt;nie może to być konstruktor, getter ani setter
&lt;li&gt;nie może być metodą klasy bazowej kontrolera
&lt;li&gt;nie może mieć parametrów &lt;b&gt;ref&lt;/b&gt; ani &lt;b&gt;out&lt;/b&gt;
&lt;li&gt;nie może mieć otwartych typów generycznych
&lt;/ol&gt;
Akcja controlera zwraca jeden z typów:&lt;br/&gt;
&lt;OL&gt;
&lt;li&gt;ViewResult &lt;!-- – Represents HTML and markup.  --&gt;
&lt;li&gt;EmptyResult &lt;!--  – Represents no result. --&gt;
&lt;li&gt;RedirectResult &lt;!--  – Represents a redirection to a new URL. --&gt;
&lt;li&gt;JsonResult &lt;!--  – Represents a JavaScript Object Notation result that can be used in an AJAX application. --&gt;
&lt;li&gt;JavaScriptResult &lt;!--  – Represents a JavaScript script. --&gt;
&lt;li&gt;ContentResult &lt;!--  – Represents a text result. --&gt;
&lt;li&gt;FileContentResult &lt;!--  – Represents a downloadable file (with the binary content). --&gt;
&lt;li&gt;FilePathResult &lt;!--  – Represents a downloadable file (with a path). --&gt;
&lt;li&gt;FileStreamResult &lt;!--  – Represents a downloadable file (with a file stream--&gt;
&lt;/ol&gt;
Typy te jednak zazwyczaj nie są zwracane jawnie. Wołamy natomiast jedną z funkcji klasy bazowej
&lt;ol&gt;
&lt;li&gt;View -&gt;  ViewResult 
&lt;li&gt;Redirect –&gt; RedirectResult  
&lt;li&gt;RedirectToAction –&gt;  RedirectToRouteResult 
&lt;li&gt;RedirectToRoute –&gt; RedirectToRouteResult
&lt;li&gt;Json –&gt; JsonResult 
&lt;li&gt;JavaScriptResult –&gt; JavaScriptResult 
&lt;li&gt;Content –&gt; ContentResult 
&lt;li&gt;File –&gt; FileContentResult, FilePathResult, FileStreamResult - w zależności od przekazanych parametrów
&lt;/ol&gt;
&lt;br/&gt;
Jeśli z akcja zwróci jakąś wartość np date - to zostanie ona automatycznie opakowana w typ &lt;b&gt;ContentResult&lt;/b&gt; - czyli przetłumaczona na zwykły tekst i jako &lt;i&gt;string&lt;/i&gt; przekazana do przeglądarki

&lt;pre name="code" class="brush:c-sharp;"&gt;
using System;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
    public class WorkController : Controller
    {
 
        public DateTime Index()
        {
            return DateTime.Now;
        }

    }
}
&lt;/pre&gt;
Jeśli nie chcemy aby metoda była akcją możemy ją udekorować &lt;b&gt;NonAction&lt;/b&gt;
&lt;pre name="code" class="brush:c-sharp;"&gt;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    public class WorkController : Controller
    {
        [NonAction]
        public string CompanySecrets()
        {
            return "This information is secret.";
        }

    }
}

&lt;/pre&gt;
&lt;br/&gt;
&lt;br/&gt;
Klasa kontrolera zawsze musi posiadać suffix &lt;b&gt;Controller&lt;/b&gt; inaczej nie będzie można wywołać kontrolera
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2407387971961003620?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2407387971961003620/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2407387971961003620&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2407387971961003620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2407387971961003620'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/mvc-c-jak-kontroler.html' title='MVC - C jak kontroler'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2119678008007416319</id><published>2009-05-20T23:23:00.011+02:00</published><updated>2009-05-21T00:11:46.560+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>IIS i błąd 413</title><content type='html'>&lt;b&gt;IIS7 Windows2008 i problem przy zapisie dużego DataSeta do bazy - błąd 413  &lt;/b&gt; &lt;br/&gt;
Błąd wydaje się być całkiem nielogiczny w sytuacji kiedy próbuję przekazać jakiegoś DataSeta do bazy, ot jedno z wielu zadań a na jednym tylko mamy błąd. W dodatku opis kompletnie nic nie wnosi w poszukiwania rozwiązania&lt;br/&gt;
&lt;b&gt;413 Request Entity Too Large&lt;/b&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
Najpierw znalazłam rozwiązanie - metodą eliminacji i porównania z innym katalogiem wirtualnym a potem dowiedziałam się dlaczego tak a nie inaczej.
&lt;br/&gt;
Zacznijmy od okoliczności przyrody. &lt;br/&gt;
Applikacja miała skonfigurowany certyfikaty &lt;br/&gt;
&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/04/06/tip-trick-enabling-ssl-on-iis7-using-self-signed-certificates.aspx"&gt;Opis konfiguracji certyfikatów&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://learn.iis.net/page.aspx/144/how-to-setup-ssl-on-iis-7/"&gt;Obszerny opis konfiguracji certyfikatów ;)&lt;/a&gt;
&lt;br/&gt;
W procesie porównawczym z nowo utworzoną aplikacją 'szwankująca' aplikacja miała poniższe ustawienie SSL
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/ShR44C39SPI/AAAAAAAAAEo/eNydI2ncPeE/s1600-h/sslSettingsA.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 174px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/ShR44C39SPI/AAAAAAAAAEo/eNydI2ncPeE/s320/sslSettingsA.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5338024362580461810" /&gt;&lt;/a&gt;

zamiast:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/ShR47Ca3HXI/AAAAAAAAAEw/OR4xRSYSbpk/s1600-h/sslSettingsI.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 174px;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/ShR47Ca3HXI/AAAAAAAAAEw/OR4xRSYSbpk/s320/sslSettingsI.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5338024413998030194" /&gt;&lt;/a&gt;
&lt;br/&gt;
Ustawienie ignorowania certyfikatów klienta oczywiście naprawiło sytuację i błąd 413 zniknął
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Co jednak jeśli konieczne jest używanie certyfikatów klienta?&lt;/b&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;a href="http://technet.microsoft.com/pl-pl/library/cc737382.aspx"&gt;Oto co mówi TechNet&lt;/a&gt;&lt;br/&gt;
A w skrócie własnymi słowami - IIS jest domyślnie zabezpieczony przed atakami DOS przez ustawienie ograniczenia dla &lt;b&gt;UploadReadAheadSize &lt;/b&gt; na 48k (49152).&lt;br/&gt;
Możliwa jest zmiana tej wartości na dowolnie większą, choć Microsoft nie zaleca przekraczania jakichśtam wartości. Do zmiany wartości naszego atrybutu musimy  zastosować skrypcik:
&lt;pre name="code" class="brush:bash;"&gt;
appcmd.exe set config  -section:system.webServer/serverRuntime /uploadReadAheadSize:"20000000"  /commit:apphost
&lt;/pre&gt;
A &lt;b&gt;appcmd&lt;/b&gt; znajdziemy w WINDOWS/SYSTEM32/INETSRV
&lt;br/&gt;
Ot cała przygoda
&lt;/span&gt;
&lt;!-- -------------------------------------------------------------------------- 
kilka linków dla mnie 
http://forums.iis.net/p/1108662/1705354.aspx
http://forums.iis.net/p/1108662/1705354.aspx
http://forums.asp.net/p/1330260/2666489.aspx
--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2119678008007416319?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2119678008007416319/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2119678008007416319&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2119678008007416319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2119678008007416319'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/iis-i-bad-413.html' title='IIS i błąd 413'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lJKm6y9ygyE/ShR44C39SPI/AAAAAAAAAEo/eNydI2ncPeE/s72-c/sslSettingsA.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-5589237548948916171</id><published>2009-05-15T00:31:00.045+02:00</published><updated>2009-05-28T23:35:55.144+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Linq to SQL / Entity Framework / DataSet - Part 2</title><content type='html'>&lt;!-- • · --&gt;
&lt;b&gt; Linq to SQL / Entity Framework / DataSet &lt;/b&gt;
&lt;br/&gt;
Skoro wiem już coś o LINQ to SQL przyszła pora na &lt;span style="font-weight:bold; color:darkblue;"&gt;Entity Framework&lt;/span&gt;
&lt;br/&gt;
&lt;span class="fullpost"&gt;
&lt;span style="font-weight:bold; color:darkblue;"&gt;Entity Framework&lt;/span&gt; miał ukazać się w VS2008 ale został opóźniony i udostępniony dopiero z VS2008 SP1&lt;br/&gt;
&lt;br/&gt;
Słownik pojęć&lt;br/&gt;
1. LINQ - technologia zapytań zintegrowanych z językiem. Sam w sobie LINQ to składnia, którą można wykorzystać do odpytywania różnych źródeł danych (baza, obiekty, XML, itd.).&lt;br/&gt;
2. LINQ to SQL - technologia mapująca bazę danych SQL Servera do postaci obiektowej i pozwalająca na odpytywanie bazy danych za pomocą składni LINQ.&lt;br/&gt;
3. Entity Framework - zaawansowana technologia mapująca dowolną bazę danych do postaci obiektowej.&lt;br/&gt;
4. LINQ to Entities - implementacja LINQ pozwalająca na wykorzystanie składni LINQ do odpytywania źródła danych Entity Framework.&lt;br/&gt;

&lt;br/&gt; Na pierwszy rzut oka wydaje się że Entity Framework wygląda to podobnie do Linq to SQL.&lt;br/&gt;
Tak naprawdę jest jego starszym bratem dużo bardziej rozbudowanym i zaawansowanym.&lt;br/&gt;
Mamy tu np relacje many-to-many, złożone wartości, oprócz wsparcia dla LINQ ma również swój wewnętrzny język Entity SQL.&lt;br/&gt;

Model entity framework składa się z trzech poziomów abstrakcji. &lt;br/&gt;
&lt;OL&gt;
&lt;li&gt; Opis bazy
&lt;li&gt; Plik mapowania
&lt;li&gt; Opis obiektów biznesowych
&lt;/OL&gt;
&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/Shcm169Q6_I/AAAAAAAAAFI/JCKax3susp0/s1600-h/entity.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/Shcm169Q6_I/AAAAAAAAAFI/JCKax3susp0/s320/entity.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5338778591072152562" /&gt;&lt;/a&gt;
&lt;br/&gt;
Takie rozwiązanie umożliwia swobodną i niezależną manipulację każdym z poziomów z osobna. &lt;br/&gt;
A tak to wygląda w VS
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/Shcot_QQ4XI/AAAAAAAAAFQ/So7z9MbyaFk/s1600-h/model.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 295px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/Shcot_QQ4XI/AAAAAAAAAFQ/So7z9MbyaFk/s400/model.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338780653809885554" /&gt;&lt;/a&gt;
&lt;br/&gt;
Mała wizualizacja architektury EF&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShdC5u6dpeI/AAAAAAAAAFY/970qgI1T35A/s1600-h/e1.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShdC5u6dpeI/AAAAAAAAAFY/970qgI1T35A/s400/e1.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5338809442884232674" /&gt;&lt;/a&gt;
Małe porównanie LINQ to SQL vs LINQ to Entities
&lt;table &gt;
 &lt;tr &gt;
   &lt;th &gt;&lt;/th&gt;
   &lt;th &gt;
        LINQ to SQL
   &lt;/th&gt;  
   &lt;th &gt;
        LINQ to Entities
   &lt;/th&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
   &lt;td&gt;Wspierane bazy danych&lt;/td&gt;
   &lt;td&gt;SQL Server&lt;/td&gt;  
   &lt;td&gt;SQL Server, DB2, Oracle, Sybase, MySQL...&lt;br/&gt;(bazuje na providerach)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr class="alt"&gt;
   &lt;td &gt;Możliwości mapowania obiektów&lt;/td&gt;
   &lt;td &gt;Proste&lt;/td&gt;  
   &lt;td &gt;Złożone (np many-to-many)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
   &lt;td&gt;Status w Microsoft&lt;/td&gt;
   &lt;td&gt;Niezbyt ważny&lt;/td&gt;  
   &lt;td&gt;Strategiczny&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr class="alt"&gt;
   &lt;td &gt;Poziom wkurzenia developera&lt;/td&gt;
   &lt;td &gt;Niewielki&lt;/td&gt;  
   &lt;td &gt;Znaczący ;)&lt;/td&gt;
 &lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
Microsoft inwestuje w Entity Framework jako produkt strategiczny i bardzo go rozwija, pozostawiając przy tym w małym zapomnieniu Linq to SQL. Jak bardzo rozwija się EF warto zobaczyć listę nowych możliwości wydaną z VS2010 Beta1  &lt;a href="http://blogs.msdn.com/adonet/archive/2009/05/21/updated-entity-framework-documentation-for-beta1.aspx"&gt;dokumentacja Entity Framework dla Beta1&lt;/a&gt;&lt;br/&gt;
Na stronie &lt;a href="http://blogs.msdn.com/data/archive/2007/04/28/microsoft-s-data-access-strategy.aspx"&gt;Microsoft'a data access strategy&lt;/a&gt;
przedstawione zostały główne punkty kiedy powinniśmy zdecydować się na używanie Entity Framework, a mianowicie jeśli potrzebujemy poniższych opcji&lt;br/&gt;

&lt;OL&gt;
&lt;li&gt;          Możliwość definiowania elastycznego mapowania do istniejącego relacyjnego schematu, np:
&lt;OL&gt;
&lt;li&gt;   Mapowanie pojedyńczego obiektu do wielu tabel

&lt;li&gt;   Używanie relacji Many-to-Many

&lt;li&gt;   Mapowanie do wybranego zapytania 
&lt;/OL&gt;
&lt;li&gt;         Możliwość użycia bazy innej niż MSSQL.

&lt;li&gt;         Możliwość dzielenia modelu z innymi produktami Microsoft jak: Replication, Reporting Services, BI, Integration Services, ...

&lt;li&gt;         Możliwość odpytywania modelu pojęciowego bez konieczności materializacji rezultatów jako obiekty
&lt;/OL&gt;
&lt;br/&gt;
&lt;br/&gt;
Temat EF jest tak rozległy że nie sposób go opisach a już na pewno nie w jednym poście.&lt;br/&gt;
Moje rozważania i porównania miały prowadzić do konkluzji którą metodę dostępu do danych wybrać. Ja pisze programik tylko do prezentacji, stąd użycie LinqToSql może być logicznym wyjściem. &lt;br/&gt;
Jednak co wybrać do nowo rozpoczynanego dużego projektu?&lt;br/&gt;
&lt;!-- 
http://blogs.msdn.com/data/archive/2007/04/28/microsoft-s-data-access-strategy.aspx
http://blogs.msdn.com/aconrad/archive/2007/12/10/linq-to-rest.aspx

http://blogs.msdn.com/adonet/archive/2008/03/26/stored-procedure-mapping.aspx

&lt;pre name="code" class="brush:c-sharp;"&gt;
&lt;/pre&gt;
--&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-5589237548948916171?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/5589237548948916171/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=5589237548948916171&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5589237548948916171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5589237548948916171'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/linq-to-sql-entity-framework-dataset.html' title='Linq to SQL / Entity Framework / DataSet - Part 2'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/Shcm169Q6_I/AAAAAAAAAFI/JCKax3susp0/s72-c/entity.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8504723173835180757</id><published>2009-05-12T23:36:00.018+02:00</published><updated>2009-06-01T10:48:49.848+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Linq to SQL / Entity Framework  / DataSet  - Part 1</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShcfP4BAc-I/AAAAAAAAAFA/JE7yg9s6ib8/s1600-h/LinqConfigureBehavior.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 282px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShcfP4BAc-I/AAAAAAAAAFA/JE7yg9s6ib8/s320/LinqConfigureBehavior.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338770240866120674" /&gt;&lt;/a&gt;

&lt;b&gt; Linq to SQL / Entity Framework  / DataSet&lt;/b&gt;
&lt;br/&gt;
A może jeszcze NHibarnate?
&lt;br/&gt;
Rozpoczęłam swoją przygodę z MVC od stworzenia jakiegoś HelloWorld według tutoriali na stronie ASP.NET. I pierwsze co wygenerowałam - to błędy przy Update, Insert.&lt;br/&gt;
Postanowiłam więc zgłębić zagadnienie literki M
&lt;br/&gt;
Każda książka czy tutorial związana z MVC gdy natrafia w opisach na literkę M tworzy bez zastanowienia Entity Data Model.&lt;br/&gt;
ASP.NET MVC framework oferuje dostęp do takiego modelu jaki sobie tylko zamarzymy i zaimplementujemy : ADO.NET, DataSet, obiekty DataReader, obiekty domenowe, ORM czyli object-relational mappers, LINQ to SQL i tak dalej...&lt;br/&gt;
Jednak najpowszechniejszą kursową techniką jest model domenowy.&lt;br/&gt;
Postanowiłam więc przyjrzeć się co to takiego i dlaczego&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;span class="fullpost"&gt;
Największe doświadczenie jak do tej pory posiadam w pracy z typowanymi DataSetami. Tworzymy sobie DataSeta z wszelkimi potrzebnymi w danym zastosowaniu tabelkami, łączymy je relacjami, przestawiamy kaskadowe usuwanie, tworzymy dla każdej tabelki minimum jedną procedurę składowaną dla polecenia Update, zazwyczaj też Insert i Delete no i jeden wielki Select. Sporo tego już, ale trzeba jeszcze zadbać o mapowanie danych i podpięcie procedur do aktualizacji danych do każdej tabelki... &lt;br/&gt;
Do wszystkiego można się przyzwyczaić. 
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight:bold; color:darkblue;"&gt;LINQ to SQL&lt;/span&gt; pojawił się już jakiś czas temu bo jak się nie mylę z VS2008, conieco się gdzieś o nim słyszało .. Zaczęłam więc tutaj.
&lt;br/&gt;
1. LINQ - technologia zapytań zintegrowanych z językiem. Sam w sobie LINQ to składnia, którą można wykorzystać do odpytywania różnych źródeł danych (baza, obiekty, XML, itd.).&lt;br/&gt;
2. LINQ to SQL - technologia mapująca bazę danych SQL Servera do postaci obiektowej i pozwalająca na odpytywanie bazy danych za pomocą składni LINQ.
&lt;br/&gt;
Pięknie, no to pierwszy tutorial 
&lt;br/&gt;Add New Item
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgyPXs4-htI/AAAAAAAAAEY/Wsw_5RgQEz0/s1600-h/linq1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 215px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgyPXs4-htI/AAAAAAAAAEY/Wsw_5RgQEz0/s320/linq1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5335797295877097170" /&gt;&lt;/a&gt;
&lt;br/&gt;
Otwiera się 'powierzchnia podobna do tej do budowania DataSeta, wyciągam więc sobie tabelki z Server Explorera.. tworzy się mapowanie z wszystkimi powiązaniami. Mogę sobie też dołożyć kilka procedur skłądowanych. 
&lt;br/&gt;
Pierwsza miło niemiła rzecz jaką robi Linq to zmiana liczby w nazwie tabeli - było Application jest Applications, gdyby było na odwrót na odwrót by się zmieniło. Rozumiem założenie, choć może być to denerwujące.&lt;br/&gt;
Robimy pierwszy select. Oczywiście aplikacja jest webowa i używam poczciwego DataGrida.

&lt;pre name="code" class="brush:c-sharp;"&gt;
 protected void Button1_Click(object sender, EventArgs e)
    {
        MojModelDataContext fgsp = new MojModelDataContext();
        var application = (from p in fgsp.Applications
                          select p);
        dataGrid.DataSource = application;
        dataGrid.DataBind();
    }
&lt;/pre&gt; 
Eureka - działa. Coś trudniejszego.
&lt;pre name="code" class="brush:c-sharp;"&gt;
 protected void Button2_Click(object sender, EventArgs e)
    {
        // Company jest powiązane z application więc możemy od razu zadać
        // pytanie linqowe z danymi z company
        MojModelDataContext fgsp = new MojModelDataContext ();
        var application = from p in fgsp.Applications
                          where p.Company.ShortName == "jakisShort".ToUpper()
                          select p;
        /*behind the scene
         zapytanie jest przerabiane na joina
         
         {SELECT 
           [t0].[ID], ... i tak dalej
         FROM [Application] AS [t0]  
         INNER JOIN [Company] AS [t1] ON [t1].[ID] = [t0].[CompanyID]  
         WHERE [t1].[ShortName] = @p0  }

         */
        dataGrid.DataSource = application;
        dataGrid.DataBind();       
    }
&lt;/pre&gt;
&lt;!--         * trzeba pamietac ze kazda nasza wymyslna konstrukcja bedzie przeksztalcona
         * na jakiegos selekt. 
         * zapewne moga byc tutaj problemy z optymalizacja zapytan
         * ale z drugiej strony -
         * mozemy zbudowac np takie wyszukiwanie jak w fgsp calkowicie po stronie
         * applikacji bez koniecznosci pisania sqla jako tekstu w procedurach
         * 
         * z mojego punktu widzenia daje to o wiele wieksze mozliwosci
         * jednak wiekszosc sqlowcow pewnie bedzie przeciwnych
--&gt;
Proste i działające, zróbmy sobie kawałek pagowania

&lt;pre name="code" class="brush:c-sharp;"&gt;
    protected void Button5_Click(object sender, EventArgs e)
    {
        MojModelDataContext fgsp = new MojModelDataContext ();
        int startRow = 0;
        var applicationdic = from p in fgsp.Applications                            
                             select p;

        dataGrid.DataSource = applicationdic.Skip(startRow).Take(4);
        dataGrid.DataBind();
    }
&lt;/pre&gt;
Jak widać pagowanie może być niezwykle proste - pomijamy ileśtam,
bierzemy ileśtam.
Wiadomo ze zapytanie linq wykonuje się w chwili odwołania do niego 
a nie w miejscu definicji
 co oznacza ze skip take - generuje nam sqla który pobiera tylko i wyłącznie
zadana paczkę danych. To jaki generuję się SQL to już inna sprawa i polecam podpatrzenie dzięki &lt;a href="http://www.scottgu.com/blogposts/linqquery/SqlServerQueryVisualizer.zip" &gt; SqlServerQueryVisualizer&lt;/a&gt; &lt;span style="font-style:italic;"&gt;(SqlServerQueryVisualizer.dll należy wrzucić do \Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers\)&lt;/span&gt;
&lt;br/&gt;
&lt;!-- SELECT [t2].[ID], [t2].[StatusID], [t2].[StatusText], [t2].[FinancialStatusID], [t2].[FinancialStatusText], [t2].[CreationDate], [t2].[LastAnalysisDate], [t2].[DaysInElaboration], [t2].[DaysToExamination], [t2].[RealizationEndDate], [t2].[MoneyToPay], [t2].[MoneyPaid], [t2].[MeritoricNo], [t2].[NoInOffice], [t2].[OfficeID], [t2].[CompanyID], [t2].[SuspensionCount], [t2].[ExtensionCount], [t2].[IsFromCourtJudgment], [t2].[FormOfPaymentID], [t2].[FormOfPaymentText], [t2].[IsDeleted], [t2].[LockedBy], [t2].[ChangeDate], [t2].[ChangeBy], [t2].[ts], [t2].[UserID], [t2].[ArchiveInventoryID], [t2].[ArchiveBriefcaseID], [t2].[CompanyAdditionalDataID], [t2].[FinalDecisionDate], [t2].[NFZID], [t2].[NFZText], [t2].[SuspendDaysCount], [t2].[FirstUserID]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ID], [t0].[StatusID], [t0].[StatusText], [t0].[FinancialStatusID], [t0].[FinancialStatusText], [t0].[CreationDate], [t0].[LastAnalysisDate], [t0].[DaysInElaboration], [t0].[DaysToExamination], [t0].[RealizationEndDate], [t0].[MoneyToPay], [t0].[MoneyPaid], [t0].[MeritoricNo], [t0].[NoInOffice], [t0].[OfficeID], [t0].[CompanyID], [t0].[SuspensionCount], [t0].[ExtensionCount], [t0].[IsFromCourtJudgment], [t0].[FormOfPaymentID], [t0].[FormOfPaymentText], [t0].[IsDeleted], [t0].[LockedBy], [t0].[ChangeDate], [t0].[ChangeBy], [t0].[ts], [t0].[UserID], [t0].[ArchiveInventoryID], [t0].[ArchiveBriefcaseID], [t0].[CompanyAdditionalDataID], [t0].[FinalDecisionDate], [t0].[NFZID], [t0].[NFZText], [t0].[SuspendDaysCount], [t0].[FirstUserID]) AS [ROW_NUMBER], [t0].[ID], [t0].[StatusID], [t0].[StatusText], [t0].[FinancialStatusID], [t0].[FinancialStatusText], [t0].[CreationDate], [t0].[LastAnalysisDate], [t0].[DaysInElaboration], [t0].[DaysToExamination], [t0].[RealizationEndDate], [t0].[MoneyToPay], [t0].[MoneyPaid], [t0].[MeritoricNo], [t0].[NoInOffice], [t0].[OfficeID], [t0].[CompanyID], [t0].[SuspensionCount], [t0].[ExtensionCount], [t0].[IsFromCourtJudgment], [t0].[FormOfPaymentID], [t0].[FormOfPaymentText], [t0].[IsDeleted], [t0].[LockedBy], [t0].[ChangeDate], [t0].[ChangeBy], [t0].[ts], [t0].[UserID], [t0].[ArchiveInventoryID], [t0].[ArchiveBriefcaseID], [t0].[CompanyAdditionalDataID], [t0].[FinalDecisionDate], [t0].[NFZID], [t0].[NFZText], [t0].[SuspendDaysCount], [t0].[FirstUserID]
    FROM [fgsp].[Application] AS [t0]
    INNER JOIN [fgsp].[DICEntry] AS [t1] ON [t1].[ID] = [t0].[StatusID]
    WHERE [t1].[Code] = @p0
    ) AS [t2]
WHERE [t2].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2
ORDER BY [t2].[ROW_NUMBER]

@p0 [String]: '01'
@p1 [Int32]: 10
@p2 [Int32]: 4 
--&gt;
&lt;br/&gt;
No to teraz Update

&lt;pre name="code" class="brush:c-sharp;"&gt;
    protected void Button6_Click(object sender, EventArgs e)
    {
        MojModelDataContext fgsp = new MojModelDataContext ();

        var applicationdic = from p in fgsp.Applications
                             select p;
        foreach (Application item in applicationdic)
        {
            item.ChangeDate = DateTime.Now; //null;// 
            //od razu mamy walidacje z obiektu - nullowalność, typy
            //a w dodatku w końcu!!
            //typy nullowalne np DateTime?
        }
        try
        {
            fgsp.SubmitChanges(); // czyli tutaj robi sie wszystko aby updatnac obiekt
        }
        catch (Exception ex)
        {
            string s = ex.Message;
        }
    }
&lt;/pre&gt;
Operacje na obiekcie wykonywane są lokalnie co jest całkiem logiczne, aby zostały wysłane do db musi zostać wywołana SubmitChanges()
 - funkcja (a raczej krasnoludki w niej ukryte) decyduje co zostało zmienione i wysyła odpowiednie updaty inserty do db.
Jeśli nie było zmiany - nie zostanie wykonany update
&lt;br/&gt;Przekazujemy wszystkie kolumny - wszystkie dane w updacie
&lt;br/&gt;         Optymistic concurrency - Jeśli zaszły jakieś zmiany w obiekcie dostajemy Exception            System.Data.Linq.ChangeConflictException 
&lt;br/&gt; SubmitChanges - wykonuje się w transakcji
 jeśli coś nie poszło - całość się cofa.
&lt;br/&gt; 
&lt;br/&gt; 
Pozostaje Insert
&lt;pre name="code" class="brush:c-sharp;"&gt;
    protected void Button7_Click(object sender, EventArgs e)
    {
        MojModelDataContext fgsp = new MojModelDataContext ();

        var apphis = fgsp.Applications.Single(p =&gt; p.ID == 952);
        //tym razem historia 
        ApplicationListChangesHistory his = new ApplicationListChangesHistory();
        his.Application = apphis;
        his.ChangeUserDate = DateTime.Now;
        
        fgsp.ApplicationListChangesHistories.InsertOnSubmit(his);        //dodajemy nowo stworzona instancje  do obiektu
        try
        {
            fgsp.SubmitChanges(); //i wywolujemy "update
        }
        catch (Exception ex) 
        {
            string s = ex.Message;
        }
    }
&lt;/pre&gt;
&lt;!-- //select * from fgsp.DICDictionary
//inner join fgsp.DICEntryGroup on DICEntryGroup.DictionaryID = fgsp.DICDictionary.ID
//inner join fgsp.DICEntry on DICEntry.GroupID = DICEntryGroup.ID
//where  DICDictionary.ID in ( 17)-

        DICEntry prev = 
            fgsp.DICEntries.Single(
            p =&gt; p.Code =="01" &amp;&amp; p.DICEntryGroup.DICDictionary.Code=="ApplicationListStatus");
        DICEntry newS = 
            fgsp.DICEntries.Single(
            p =&gt; p.Code == "08" &amp;&amp; p.DICEntryGroup.DICDictionary.Code == "ApplicationListStatus");
        //ten zapis wydaje mi sie bardzo przyjemny i latwy do odnalezienia sie
        // przy okazji daje duze mozliwosci wpiecia w obecna strukture frameworkaSNT
        //poniewaz latwo bedzie wymienic operacje pozostawiajac sens funkcji



his.ChangeUserID = 371;
        //rownie dobrze moge uzyc idkow ale je i tak musze wyciagnac
        // a patrzac na rozwiazanie fgsp i tak mamy obiekty albo je tworzymy
        his.IsDeleted = false; 
        //his.ts 
        //z milych rzeczy - TS 
        //w obiektach jest property TimeStamp i Auto-Sync ktore wydaja mi sie
        //stworzone dla ts
        //innymi slowy - nie musimy sie nim przejmowac - sam sie stworzy


        /*
             #region Extensibility Method Definitions
           kazda z klas ma taki region
         * a w nim mnustwo metod ktore moga byc nadpisane 
         * - mozna latwo dodac dodawanie nowych elementow, czy walidacji
         * 
         */
--&gt;
&lt;br/&gt;


&lt;br/&gt; Możliwe jest też rozszerzanie modelu. Mamy do wyboru funkcje typu OnPropertieChanged() OnPropertieChanged() OnCreated() OnValidation() można coś potworzyć sensownego.
&lt;br/&gt;     
&lt;br/&gt;
Dodajmy sobie jeszcze swoją procedurkę do obsługi np Inserów&lt;br/&gt;
Na "tabelce" w menu podręcznym wybieramy &lt;b&gt;Configure Behavior&lt;/b&gt; lub w oknie Properties wybieramy Insert...&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShceHY_es3I/AAAAAAAAAE4/M1Bg1ZOGPoE/s1600-h/linqInsert.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShceHY_es3I/AAAAAAAAAE4/M1Bg1ZOGPoE/s320/linqInsert.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338768995587634034" /&gt;&lt;/a&gt;
&lt;br/&gt;
Pojawia się okno konfiguracji w którym domyślnie ustawione jest "Use runtime". Po przestawieniu na Customize mamy możliwość wyboru funkcji (wcześniej dodanej do naszego dbml modelu). Jeśli pola w metodzie i pola w obiekcie zgadzają się co do 
nazwy - zostaną automatycznie podmapowane, jeśli nazwy się nie zgadzają musimy to sobie wyklikać.&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShcfP4BAc-I/AAAAAAAAAFA/JE7yg9s6ib8/s1600-h/LinqConfigureBehavior.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 282px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/ShcfP4BAc-I/AAAAAAAAAFA/JE7yg9s6ib8/s320/LinqConfigureBehavior.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338770240866120674" /&gt;&lt;/a&gt;
&lt;br/&gt;
Możliwe jest wybranie np tylko funkcji do Insert wtedy Update i Delete nadal będą generowane automatycznie at runtime.&lt;br/&gt;
&lt;br/&gt;
Stety/Niestety nie ma takiej samej opcji dla select.

&lt;br/&gt; &lt;br/&gt; 
&lt;b&gt; Porównując tą metodę do pobierania wszystkiego do DataSetu...&lt;/b&gt; cóż tu dużo mówić nie trzeba się tyle nastukać rzeczy autogenerujących się. Oczywiście nie jesteśmy pozostawieni na łasce tego co zostanie wygenerowane, możemy sobie podpiąć własne procedury składowane do Insertów Updatów Deletów na poszczególnych tabelkach - ale możemy znaczy nie musimy.
Do tego pagowanie &lt;br/&gt; Ale to tylko aplikacja 'na pokaz' nie ma tu nic skomplikowanego, na pewno problemy pojawiły by się potem, jednak czy nie lepiej być optymistą ;)
&lt;!--

&lt;br/&gt;
&lt;br/&gt;
Kilka linków
&lt;br/&gt;

&lt;a href="http://www.thedatafarm.com/Blog/2007/04/04/LINQToSQLVsEntityFramework.aspx" &gt;LINQToSQLVsEntityFramework &lt;/a&gt;
&lt;br/&gt;
&lt;a href="http://dotnetaddict.dotnetdevelopersjournal.com/adoef_vs_linqsql.htm" &gt;
adoef_vs_linqsql&lt;/a&gt;
&lt;br/&gt;
&lt;a href="http://rafalb.com/Blog.aspx?id=7" &gt; rafalb&lt;/a&gt;
&lt;br/&gt;


Na początek krótkie wyjaśnienie, żeby nie mylić pojęć ;)
1. LINQ - technologia zapytań zintegrowanych z językiem. Sam w sobie LINQ to składnia, którą można wykorzystać do odpytywania różnych źródeł danych (baza, obiekty, XML, itd.).
2. LINQ to SQL - technologia mapująca bazę danych SQL Servera do postaci obiektowej i pozwalająca na odpytywanie bazy danych za pomocą składni LINQ.
3. Entity Framework - zaawansowana technologia mapująca dowolną bazę danych do postaci obiektowej.
4. LINQ to Entities - implementacja LINQ pozwalająca na wykorzystanie składni LINQ do odpytywania źródła danych Entity Framework.

Teraz sprawa jest prosta. Żeby operować na bazie możesz wykorzystać m.in. LINQ to SQL albo Entity Framework. Obu używa się w miarę podobnie (choć w szczegółach różnice stają się kolosalne) i potrafią zamapować dowolną bazę. Osobiście polecałbym LINQ to SQL, bo jest trochę prostsza.

PS. Sory za łopatologiczność, ale chcę żebyśmy się na pewno dobrze zrozumieli :).


&lt;pre name="code" class="brush:c-sharp;"&gt;
&lt;/pre&gt; --&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8504723173835180757?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8504723173835180757/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8504723173835180757&amp;isPopup=true' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8504723173835180757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8504723173835180757'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/linq-to-sql-entity-framework-moze.html' title='Linq to SQL / Entity Framework  / DataSet  - Part 1'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/ShcfP4BAc-I/AAAAAAAAAFA/JE7yg9s6ib8/s72-c/LinqConfigureBehavior.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-8631963414838093201</id><published>2009-05-07T00:13:00.017+02:00</published><updated>2009-05-12T21:46:22.605+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wzorce projektowe'/><title type='text'>Strategia</title><content type='html'>&lt;b&gt;Wzorzec strategi&lt;/b&gt;
&lt;br/&gt;
Mały opis i trochę przykładowego kodu na temat wzorca strategii. &lt;br/&gt;
Mając klasę abstrakcyjną pojazdów z bardzo sprytną funkcją "go" implementujemy sobie różne pojazdy, dziedziczące po Vehicle.

&lt;span class="fullpost"&gt;

&lt;pre name="code" class="brush:c-sharp;"&gt;
    public abstract class Vehicle
    {
        public Vehicle() { }
        public virtual string go()
        { return "Jadę"; }
    }

    public class Car: Vehicle
    {
        public Car() { }
    }

    public class Helicopter : Vehicle
    {
        public Helicopter() { }
    }

    public class Jet: Vehicle
    {
        public Jet() { }
    }
&lt;/pre&gt;
Pojawia się problem że tak naprawdę funkcyjka go jest oderwana od rzeczywistości bo helikoptery nie jeżdżą tylko latają.&lt;br/&gt;
To co możemy zrobić to przeciążenie funkcji go:
&lt;pre name="code" class="brush:c-sharp;"&gt;
public class Helicopter : Vehicle
    {
        public Helicopter() { }
        public override string go()
        {
            return "Lecę";
        } 
    }

&lt;/pre&gt;
Pojawia się problem który wymusił powstanie wzorca strategi.&lt;br/&gt;
Jeśli będziemy przeciążać każdą potrzebną funkcję oczywiście uzyskamy pożądany efekt, jednak po pewnym czasie stworzy się bardzo dużo generacji dziedziczenia i wersji obiektów - co w linii prostej prowadzi do trudnego i żmudnego utrzymania kodu.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIWfNDC5xI/AAAAAAAAAEI/VMWybSoLhq4/s1600-h/classIsA.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 69px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIWfNDC5xI/AAAAAAAAAEI/VMWybSoLhq4/s320/classIsA.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332849634094278418" /&gt;&lt;/a&gt;
&lt;br/&gt;
Wzorzec strategi sugeruje aby używać obiektu ze zmienna algorytmu. Pomysł opiera się na wyizolowaniu 'drażliwego' kodu do obiektów algorytmów. Wewnątrz klasy poprzez zmienna algorytmu możliwe jest używanie różnych obiektów algorytmów.&lt;br/&gt;&lt;br/&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIXpeegCgI/AAAAAAAAAEQ/FQ5r4h1IPNM/s1600-h/classHasA.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 201px;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIXpeegCgI/AAAAAAAAAEQ/FQ5r4h1IPNM/s320/classHasA.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332850910083156482" /&gt;&lt;/a&gt;
To inne spojrzenie na programowanie obiektowe. Używając strategi mamy do czynienia ze związkiem 'has a' czyli 'posiada' obiekt, a nie 'is a' czyli 'jest' danego typu (w hierarchii dziedziczenia).
&lt;br/&gt;&lt;br/&gt;
Teraz przepiszmy ten prosty przykład z pojazdami zgodnie z wytycznymi strategii.
&lt;pre name="code" class="brush:c-sharp;"&gt;
    public interface GoAlgorith
    {
        public string go();
    }

    public class GoByDrivingAlgorithm : GoAlgorith
    {
        public string go()
        { return "Jadę"; }
    }

    public class GoByFlying : GoAlgorith
    {
        public string go()
        { return "Lecę"; }
    }
    public class GoByFlyingFast : GoAlgorith
    {
        public string go()
        { return "Lecę szybciutko"; }
    }
//-------------------------------------
    public abstract class Vehicle
    {
        public Vehicle() { }
        private GoAlgorith goAlgorithm;
        public void setGoAlgorithm(GoAlgorith algorithm)
        { goAlgorithm = algorithm; }

        public virtual string go()
        { return goAlgorithm.go(); }
    }

    public class Car : Vehicle
    {
        public Car() { setGoAlgorithm(new GoByDrivingAlgorithm()); }
    }

    public class Helicopter : Vehicle
    {
        public Helicopter() { setGoAlgorithm(new GoByFlying();}
    }

    public class Jet : Vehicle
    {
        public Jet() {setGoAlgorithm(new GoByFlyingFast(); }
    }
&lt;/pre&gt;
&lt;br/&gt;
Klasy Car, Helicopter i Jet przechowują konkretny algorytm będący kontekstem do strategii. Ze względu na wybór algorytmu wykonywane mogą być różne czynności.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-8631963414838093201?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/8631963414838093201/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=8631963414838093201&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8631963414838093201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/8631963414838093201'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/strategia.html' title='Strategia'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIWfNDC5xI/AAAAAAAAAEI/VMWybSoLhq4/s72-c/classIsA.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-2709853624191607941</id><published>2009-05-06T23:36:00.007+02:00</published><updated>2009-05-06T23:42:13.709+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Wzorce projektowe'/><title type='text'>MVC wstęp od strony Wzorców Projektowych part 3</title><content type='html'>&lt;b&gt;Wracając do klasyfikacji wzorców interesujemy się trzema wyróżnionymi&lt;/b&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIDQAhGw3I/AAAAAAAAACQ/TFrYqJ3jCeU/s1600-h/Slajd12.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIDQAhGw3I/AAAAAAAAACQ/TFrYqJ3jCeU/s320/Slajd12.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332828482311734130" /&gt;&lt;/a&gt;
Wzorce projektowe związane z każdym elementem
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgIDX0hF3uI/AAAAAAAAACY/PPkfVlTUY18/s1600-h/Slajd13.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgIDX0hF3uI/AAAAAAAAACY/PPkfVlTUY18/s320/Slajd13.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332828616529403618" /&gt;&lt;/a&gt;
Wzorzec projektowy Kompozyt
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIDfssPaII/AAAAAAAAACg/TaFu4IArlwA/s1600-h/Slajd14.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIDfssPaII/AAAAAAAAACg/TaFu4IArlwA/s320/Slajd14.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332828751867635842" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgIDj9wgkAI/AAAAAAAAACo/2gFL-fgvc3c/s1600-h/Slajd15.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgIDj9wgkAI/AAAAAAAAACo/2gFL-fgvc3c/s320/Slajd15.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332828825168416770" /&gt;&lt;/a&gt;
Wzorzec projektowy Obserwator
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgIDs7roI1I/AAAAAAAAACw/ZmjoszDqNQ8/s1600-h/Slajd16.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgIDs7roI1I/AAAAAAAAACw/ZmjoszDqNQ8/s320/Slajd16.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332828979229893458" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIDxeGQVII/AAAAAAAAAC4/nAebyau6Fww/s1600-h/Slajd17.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_lJKm6y9ygyE/SgIDxeGQVII/AAAAAAAAAC4/nAebyau6Fww/s320/Slajd17.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332829057187861634" /&gt;&lt;/a&gt;
Wzorzec projektowy Strategia
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgID54Et7fI/AAAAAAAAADA/gV3A24v_uh0/s1600-h/Slajd18.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgID54Et7fI/AAAAAAAAADA/gV3A24v_uh0/s320/Slajd18.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332829201599688178" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgID_sIEJoI/AAAAAAAAADI/bBow7Xz93y8/s1600-h/Slajd19.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgID_sIEJoI/AAAAAAAAADI/bBow7Xz93y8/s320/Slajd19.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332829301471716994" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-2709853624191607941?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/2709853624191607941/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=2709853624191607941&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2709853624191607941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/2709853624191607941'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/mvc-wstep-od-strony-wzorcow_9596.html' title='MVC wstęp od strony Wzorców Projektowych part 3'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIDQAhGw3I/AAAAAAAAACQ/TFrYqJ3jCeU/s72-c/Slajd12.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-798285301712415379</id><published>2009-05-06T23:28:00.002+02:00</published><updated>2009-05-06T23:35:16.378+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Wzorce projektowe'/><title type='text'>MVC wstęp od strony Wzorców Projektowych part 2</title><content type='html'>&lt;div style="font-weight:bold; text-align:center; margin-top:10px; padding-top:10px; margin-bottom:10px; padding-bottom:10px; "&gt;Model Widok Kontroler&lt;/div&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgIBzvVucBI/AAAAAAAAABo/lSP7GvgCE4Y/s1600-h/Slajd6.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_lJKm6y9ygyE/SgIBzvVucBI/AAAAAAAAABo/lSP7GvgCE4Y/s320/Slajd6.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332826897152634898" /&gt;&lt;/a&gt;
Trzy elementy omawianego wzorca:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgICF3RkkcI/AAAAAAAAABw/mJ3Qx5Uh1Gk/s1600-h/Slajd8.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgICF3RkkcI/AAAAAAAAABw/mJ3Qx5Uh1Gk/s320/Slajd8.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332827208520339906" /&gt;&lt;/a&gt;
A teraz akcje pomiędzy komponentami MVC:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgICP8Q32oI/AAAAAAAAAB4/zpRY5GD5E6w/s1600-h/Slajd9.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgICP8Q32oI/AAAAAAAAAB4/zpRY5GD5E6w/s320/Slajd9.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332827381658278530" /&gt;&lt;/a&gt;
Role elementów:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgICXmJMldI/AAAAAAAAACA/WJa-wzmJccM/s1600-h/Slajd10.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgICXmJMldI/AAAAAAAAACA/WJa-wzmJccM/s320/Slajd10.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332827513159456210" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgICfB77VsI/AAAAAAAAACI/dh7QiziZiAE/s1600-h/Slajd11.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgICfB77VsI/AAAAAAAAACI/dh7QiziZiAE/s320/Slajd11.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332827640879077058" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-798285301712415379?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/798285301712415379/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=798285301712415379&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/798285301712415379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/798285301712415379'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/mvc-wstep-od-strony-wzorcow_06.html' title='MVC wstęp od strony Wzorców Projektowych part 2'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lJKm6y9ygyE/SgIBzvVucBI/AAAAAAAAABo/lSP7GvgCE4Y/s72-c/Slajd6.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-9071960018386770810</id><published>2009-05-06T23:13:00.007+02:00</published><updated>2009-05-06T23:28:26.695+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Wzorce projektowe'/><title type='text'>MVC wstęp od strony Wzorców Projektowych part 1</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgH_brNR7EI/AAAAAAAAABA/j5krY8uiiSQ/s1600-h/Slajd1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgH_brNR7EI/AAAAAAAAABA/j5krY8uiiSQ/s320/Slajd1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332824284703353922" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgH_pJ8EkLI/AAAAAAAAABI/HYs1J1wKAvk/s1600-h/Slajd2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lJKm6y9ygyE/SgH_pJ8EkLI/AAAAAAAAABI/HYs1J1wKAvk/s320/Slajd2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332824516290973874" /&gt;&lt;/a&gt;

&lt;br/&gt;
Szukając informacji o MVC zaczęłam od wzorców projektowych ponieważ ten kierunek wydał się w jakiś sposób najbardziej logiczny .
&lt;br/&gt;
Wzorce projektowe.&lt;br/&gt;
Wzorce projektowe wywodzą się od podobnego pomysłu w architekturze, mającego ułatwiać konstruowanie mieszkań i pomieszczeń biurowych. Pomysł jednak się nie przyjął. &lt;br/&gt;
Pomysł podłapał Kent Beck twórca programowanie ekstremalnego i manifestu zwinnego oprogramowania i od niego się zaczęło. &lt;br/&gt;
Wzorce projektowe to uniwersalne sprawdzone rozwiązania często pojawiających się powtarzalnych problemów. Nie są to gotowe implementacje a raczej opisy.&lt;br/&gt;
Zamiast skupiać się na funkcjonowaniu poszczególnych elementów, wzorce projektowe stanowią abstrakcyjny opis zależności pomiędzy klasami, co w efekcie doprowadza do pewnej standaryzacji kodu i czyni go bardziej zrozumiałym, efektywniejszym i mniej zawodnym.&lt;br/&gt;
Wzorce projektowe mogą przyspieszyć proces rozwoju oprogramowania przez dostarczenie wypróbowanych rozwiązań dla problemów. &lt;br/&gt;
A jak to się mówi wszystko zostało już napisane wystarczy znaleźć odpowiedni kawałek kodu – w tym przypadku przepis na napisanie tego kawałka kodu.&lt;br/&gt;
Wzorce projektowe to bardzo małe elementy i jako przykłady można wymienić „Fabrykę abstrakcyjną”, Prototyp, Singelton, Adapter, Mediator czy Obserwator.&lt;br/&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIAT39fUPI/AAAAAAAAABY/9588fqBwDIw/s1600-h/Slajd4.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIAT39fUPI/AAAAAAAAABY/9588fqBwDIw/s320/Slajd4.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332825250199458034" /&gt;&lt;/a&gt;
&lt;br/&gt;
Mówiąc o MVC zawsze posługujemy się pojęciem wzorca projektowego, jednak jest to trochę bardziej skomplikowane. Po zapytaniu niezawodnej Wikipedii (której autor również dołożył się do dzieła pana Back’a) znajdujemy termin:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIAZn9IefI/AAAAAAAAABg/yie2fBekB1o/s1600-h/Slajd5.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lJKm6y9ygyE/SgIAZn9IefI/AAAAAAAAABg/yie2fBekB1o/s320/Slajd5.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332825348982209010" /&gt;&lt;/a&gt;

&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-9071960018386770810?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/9071960018386770810/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=9071960018386770810&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9071960018386770810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9071960018386770810'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/mvc-wstep-od-strony-wzorcow.html' title='MVC wstęp od strony Wzorców Projektowych part 1'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lJKm6y9ygyE/SgH_brNR7EI/AAAAAAAAABA/j5krY8uiiSQ/s72-c/Slajd1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-9087030516359229803</id><published>2009-05-06T19:23:00.032+02:00</published><updated>2009-05-07T01:11:22.565+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Css'/><title type='text'>FileUpload Input Size</title><content type='html'>Jakże miłe są nieudokumentowane możliwości.&lt;br/&gt;
Problem - korzystając z kontrolki  FileUpload wygląd zdecydowanie różni się w FF i IE - IE rysuje dłuższy input adresu, natomiast ff jakoś go skraca. Oczywiście można to obejść składając odpowiednik z dwóch innych kontrolek.&lt;br/&gt;
Jest jednak możliwość ustalenia długości TextBoxa bez zmiany kontrolki.&lt;br/&gt;
Property &lt;b&gt;Size &lt;/b&gt;
&lt;br/&gt;
&lt;table &gt;
&lt;tr&gt;
&lt;td style="background-color:white; color:blue"&gt;&lt;&lt;/td&gt;
&lt;td style="background-color:white; color:brown"&gt; asp:FileUpload &lt;/td&gt;
&lt;td style="background-color:white; color:red"&gt;ID&lt;/td&gt;
&lt;td style="background-color:white; color:blue"&gt;="fileUploadImport"&lt;/td&gt;
&lt;td style="background-color:white; color:red"&gt; runat&lt;/td&gt;
&lt;td style="background-color:white; color:blue"&gt;="server"&lt;/td&gt;
&lt;td style="background-color:white; color:red"&gt;  Width&lt;/td&gt;
&lt;td style="background-color:white; color:blue"&gt;="80%" &lt;/td&gt;
&lt;td style="background-color:white; color:red"&gt; Size&lt;/td&gt;
&lt;td style="background-color:white; color:blue"&gt; ="120" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;pre name="code" class="brush:html;"&gt;
&lt;asp:FileUpload ID="fileUploadImport" runat="server" Width="80%" Size="120" /&gt;
&lt;/pre&gt;
Size - określa wielkość TextBoxa w którym prezentowana jest ścieżka dla komponentu FileUpload
&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-9087030516359229803?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/9087030516359229803/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=9087030516359229803&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9087030516359229803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/9087030516359229803'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/05/jakze-mie-sa-nieudokumentowane.html' title='FileUpload Input Size'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-5343491838159780976</id><published>2009-05-01T01:34:00.008+02:00</published><updated>2011-07-05T20:27:59.360+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Beginning'/><title type='text'>SyntaxHighlighter</title><content type='html'>Skoro kod to szukałam czegoś do podświetlania składni. I tak oto natrafiłam na &lt;a href="http://code.google.com/p/syntaxhighlighter"&gt;
SyntaxHighlighter&lt;/a&gt; i teraz pora go wypróbować.
&lt;pre name="code" class="brush:c-sharp;"&gt;
private void HelloWorld()
{
 string _message = "Hellow SyntaxHighlighter";
}
&lt;/pre&gt;

Jedyne co trzeba pamiętać to aby w ustawieniach wyłączyć znaczniki nowej linii aby nie dodawały się zbędnie do kodu
&lt;br/&gt;
&lt;br/&gt;
Niestety nie znalazłam możliwości podświetlania składni ASP :(
&lt;br/&gt;
&lt;!-- http://coderstalk.blogspot.com/2008/06/how-to-create-expandable-post-summaries.html  jak zrobic zwijalne --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-5343491838159780976?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/5343491838159780976/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=5343491838159780976&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5343491838159780976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/5343491838159780976'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/04/skoro-kod-to-szukaam-czegos-do_30.html' title='SyntaxHighlighter'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8254280458207814344.post-3762967602182857800</id><published>2009-05-01T01:01:00.001+02:00</published><updated>2009-05-06T20:12:51.488+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Beginning'/><title type='text'>Beginning</title><content type='html'>Czy introwertyczny programista wywnętrznia się publicznie na blogu?
Być może wywnętrzniać się nie będę ale mam w zamiarze zamieszczać tutaj jakieś skrawki opowieści o wygranych wojnach programistycznych.
Co z tego wyjdzie zobaczymy.&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8254280458207814344-3762967602182857800?l=jlfedra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlfedra.blogspot.com/feeds/3762967602182857800/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8254280458207814344&amp;postID=3762967602182857800&amp;isPopup=true' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3762967602182857800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8254280458207814344/posts/default/3762967602182857800'/><link rel='alternate' type='text/html' href='http://jlfedra.blogspot.com/2009/04/beginning.html' title='Beginning'/><author><name>JL</name><uri>http://www.blogger.com/profile/04978235759110624501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='20' height='32' src='http://3.bp.blogspot.com/_lJKm6y9ygyE/Sfo5eWEZuFI/AAAAAAAAAAM/A5ktjQOSDv8/S220/KushielsScion_sm1.jpg'/></author><thr:total>0</thr:total></entry></feed>
