Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Simple.Data - rewelacyjna biblioteka .NET ORM bez ORMa!

W tym wpisie pragnę przedstawić krótkie wprowadzenie do genialnej w swojej prostocie biblioteki Simple.Data dla platformy .NET.

Otóż zapewne każdy kto miał styczność z programowaniem, musiał w pewnym momencie skorzystać z bazy danych. Wówczas najczęściej pada wybór na Entity Framework lub (Fluent) nHibernate jako framework ORM. Pociąga to za sobą tworzenie obiektów (Object), posiadanie relacyjnej bazy danych (Relational), a także stworzenie relacji (Mapping). Oczywiście każdy z tych frameworków posiada generator dla obiektów i relacji. Jednakże pomimo tych udogodnień, stworzenie ich wymaga zawsze poświęcenia czasu. Co więcej, jeśli baza nie jest budowana razem z projektem, a opiera się już na istniejącej, wówczas wymaga to jeszcze więcej pracy. Każda z bibliotek jest bardzo wrażliwa na wszelkie niestandardowe rozwiązania lub nieścisłości. Te zaś występują często w istniejących już bazach, które współdzielone są przez kilka aplikacji. Jakakolwiek zmiana w takim przypadku nie wchodzi w rachubę. Odpowiednie skonfigurowanie wszystkiego, aby później nie sprawiało już problemów, jest pracochłonne.

Jeśli nasz projekt korzysta z bazy danych okazjonalnie i/lub nie wymaga niesamowitych skomplikowanych operacji, wówczas wdrożenie Entity Framework lub (Fluent) nHibernate nie jest zbyt opłacalne. Szczególnie, gdy z wielu istniejących tabel, mających wiele relacji, będziemy używać zaledwie kilku. W tym momencie idealnym rozwiązaniem jest Simple.Data!

Simple.Data - ORM bez ORMa

Simple.Data jest lekkim frameworkiem dla .NET, który zapewnia dostęp do bazy w stylu ORM, ale bez obiektów (Object), bez wymogu łączenia się do relacyjnej bazy danych (Relational) a także bez generowania relacji (Mapping)! Wszystko dzięki typom dynamicznym w .NET 4!

Simple.Data posiada adaptery do:

  • ADO.NET obsługuje następujące bazy:
    • SQL Server 2005 i nowsze
    • SQL Server Compact Edition 4.0
    • Oracle
    • VistaDB
    • MySQL 4.0 i nowsze
    • SQLite 3.0 i nowsze
    • PostgreSQL
    • SQLAnywhere
    • Informix
  • MongoDB
  • OData
  • Azure
  • Wymagania i konfiguracja

    Dla platformy .NET wymagana jest wersja 4 lub wyższya, zaś jeśli chcemy używać Simple.Data z Mono, musimy posiadać wersję co najmniej 2.1. Aktualna wersja znajduje się na githubie, ale najprościej pobrać ją poprzez NuGeta.

    Zawsze do poprawnego działania wymagana jest biblioteka Simple.Data.Core oraz biblioteka Simple.Data dla konkretnego adaptera (ADO.NET, MongoDB, OData, Azure). Wybierając adapter ADO.NET należy dołożyć jeszcze bibliotekę Simple.Data dla konkretnej bazy, z jaką będziemy działać.

    Jedynie co należy skonfigurować to... connection string. Można trzymać go zarówno w pliku .config, jak i podać jako argument przy otwieraniu połączenia z bazą danych. Oczywiście nie ma ograniczenia do ilości połączeń. Tutaj mała uwaga, Simple.Data nie utrzymuje połączenia, a zatem obiekt zwrócony z Database.Open() można przetrzymywać w singletonie, jeśli jest taka potrzeba. Gdy specyfikacja projektu nie pozwoliłaby na to, nic nie stoi na przeszkodzie, aby samemu zarządzać kiedy następuję połączenie/rozłączenie (szczegóły).

    Jak to działa?

    Otóż język .NET 4 wprowadził m.in. dynamiczne typy. Simple.Data wykorzystuje to w sprytny sposób. Korzystając z kilkudziesięciu zdefiniowanych metod i łącząc je z z tym, co chcemy pobrać z bazy, uzyskujemy bardzo prosty i szybki framework. Poniżej kilka przykładów przedstawiających Simple.Data. Dzięki nim łatwiej będzie zrozumieć, jak ta biblioteka świetnie nadaje się do małych i średnich projektów, które nie wymagają zaprzęgania wielkich frameworków ORM.

    Prosty przykład

    Nadeszła pora, aby pokazać jak to działa w praktyce. Dzięki czemu można uzmysłowić sobie jak szybkim i elastycznym frameworkiem jest Simple.Data. Oto "książkowy" przykład, jak robimy to w standardowy, klasyczny sposób:

    public Book FindBookById(int id) { Book book = null; using (var connection = new SqlConnection(ConfigurationManager .ConnectionStrings["Default"].ConnectionString)) using (var command = new SqlCommand("SELECT [Id],[WriterId],[Name],[Year]"+ "FROM [Book] where id= @id", connection)) { command.Parameters.Add("@id", SqlDbType.Int).Value = id; connection.Open(); using (var reader = command.ExecuteReader()) { if (reader.Read()) { book = new Book { Id = reader.GetInt32(0), WriterId = reader.GetString(1), Name = reader.GetString(2), Year = reader.GetString(3) }; } } } return book; }

    a teraz to samo, ale z Simple.Data (bez generowania czegokolwiek!):

    public Book FindBookById(int id) { return Database.Open().Books.FindAllById(id).FirstOrDefault(); }

    czy jeszcze prościej bez żadnych klas:

    var book = Database.Open().FindAllById(2).FirstOrDefault();

    Jak to działa na powyższym przykładzie?

    • Database.Open() - w tym miejscu nawiązywane jest połączenie. Metoda Open bez parametru, pobiera domyślny connection string z configu i zwraca łącznik bazy. Co ciekawe Database jest jedynym niedynamicznym obiektem.
    • Books - domyślnie kolejnym elementem jest nazwa tabeli/widoku. Liczba pojedyncza/mnoga nie ma znaczenia. Czy użyjemy Book, czy Books, Simple.Data i tak stworzy poprawny zapytanie. W powyższym przykładzie - Books - spowoduje, iż framework stworzy kilka możliwych wersji (Books, books, book) i spróbuje znaleźć pasującą nazwę w INFORMATION_SCHEMA.TABLES
    • FindAllById - ten wyrażenie to połączenie kilku elementów. Metody: FindAllBy, która oznacza, iż chcemy pobrać rekordy o zadanym, co najmniej jednym warunku. W tym przypadku jest to Id. Oczywiście można dodawać ich więcej np. FindAllByYearAndWriterId("2011", 1). Warto dodać, że istnieje również alternatywna metoda tworzenia zapytań np. FindAllBy(Year: "2011", WriterId: 1) (dla niektórych bardziej czytelne).
    Tak naprawdę to tylko tyle ;) Wygenerowany w taki sposób kod SQL wygląda następująco: SELECT [dbo].[book].[id], [dbo].[book].[writerid], [dbo].[book].[name], [dbo].[book].[year], [dbo].[book].[description] FROM [dbo].[book] WHERE [dbo].[book].[id] = @p1 (@p1 (Int32) = 2)

    Coś trudniejszego - JOIN

    Powyższy przykład był dość prosty, teraz coś ciekawszego: JOIN. Otóż w Simple.Data jest to równie trywialne. Rozpatrzmy jednak dwa przypadki.

    • istnieją odpowiednie klucze obce w tabelach

    var db = Database.Open(); var books = db.Books.FindAllByYear("2011") .Select( db.Books.Name, db.Books.Writer.FirstName);

    W tym przypadku pobieramy wszystkie książki (Books) z roku 2011, łącząc przy okazji z autorem książki (Writer). Dodatkowo, dzięki Select, można było wybrać, które kolumny mają być zwrócone. Wszystkie kolumny można wybrać używając metody Star().

    SELECT [dbo].[book].[name], [dbo].[writer].[firstname] FROM [dbo].[book] LEFT JOIN [dbo].[writer] ON ( [dbo].[writer].[id] = [dbo].[book].[writerid] ) WHERE [dbo].[book].[year] = @p1 (@p1 (String) = 2011)

    Przypominam - automatyczne połączenie JOIN może powstać, gdy odpowiednio oznaczone są klucze obce w tabelach.

    • brak kluczy obcych

    var db = Database.Open(); var books = db.Books.FindAllByYear("2011") .Select( db.Books.Name, db.Books.Writer.FirstName) .LeftJoin(db.Writer).On(db.Writer.Id == db.Books.WriterId);

    Ja widać, LeftJoin pozwala na połączenie tabel, które nie mają założonych kluczy obcych. W ten prosty sposób można połączyć dwie tabele po odpowiednich kolumnach.

    Wygenerowany kod przedstawia się następująco:

    SELECT [dbo].[book].[name], [dbo].[writer].[firstname] FROM [dbo].[book] LEFT JOIN [dbo].[writer] ON ( [dbo].[writer].[id] = [dbo].[book].[writerid] ) WHERE [dbo].[book].[year] = @p1 @p1 (String) = 2011

    Poziom wyższy - stronicowanie

    Tera coś ciekawszego, co może przydać się często w przypadku tworzenia małych CRMów. Otóż jak wyglądać będzie pobieranie danych ze stronicowaniem (idealne do grida)? Simple.Data i w tym przypadku zaskakuje, pozytywnie!

    Aby nie komplikować kodu załóżmy, że chcemy robić stronicowanie tabeli z książkami (Books). Oczywiście ma pojawiać się również ogólna ilość rekordów i opcja sortowania. Napisanie tego w SQL wymaga trochę klepania. Jak wygląda to w Simple.Data? Trzymajcie się ;)

    var db = Database.Open(); Future < int > count; var books = db.Books.All() .OrderByDescending(db.Books.Name) .WithTotalCount(out count) .Skip(5) .Take(2) .ToList();

    Czyż to nie jest proste? Cóż ten wielce skomplikowany kod robi :) Dla tabeli Book brane są wszystkie rekordy (All). Następnie zostają one posortowane (OrderByDescending) po nazwie. Stronicowanie załatwiają dwie metody: Skip i Take. Pierwsza przeskakuje o zadaną ilość rekordów, a druga pobiera dokładnie tyle elementów, ile chcemy. Piękne.

    Jak wygląda wygenerowany kod SQL?

    SELECT Count(*) FROM [dbo].[book]; WITH __data AS (SELECT [dbo].[book].[id], [dbo].[book].[writerid], [dbo].[book].[name], [dbo].[book].[year], [dbo].[book].[description], Row_number() OVER( ORDER BY [dbo].[book].[name] DESC) AS [_#_] FROM [dbo].[book]) SELECT [id], [writerid], [name], [year], [description] FROM __data WHERE [_#_] BETWEEN 6 AND 7

    Jak dla mnie, jak najbardziej poprawnie i do zaakceptowania. A robi to taki mały kawałeczek kodu!

    Simple.Data - szybkość i prostota

    Przedstawiłem zaledwie mały wycinek funkcjonalności jakie posiada Simple.Data. Nie pisałem o tak trywialnych rzeczach jak dodawanie, aktualizowanie, usuwanie rekordów. Biblioteka oferuje również wsparcie dla testów jednostkowych, czy nawet wykonywanie procedur (przypominam sobie zabawy z nimi w Fluent nHibernate)! Więcej możliwości znajdziemy w dokumentacji, która nie zawsze jest aktualizowana, po najnowsze zmiany i nowinki polecam gorąco, zajrzeć na blog autora.

    Simple.Data jest genialnym, niewielkim i szybkim frameworkiem do małych i średnich
    projektów. Pomimo prostoty, posiada bogatą funkcjonalność, a ilość obsługiwanych typów baz, zachwyca. Nie ma oczywiście "róży bez ognia". Całkowita dynamiczność wiąże za sobą brak jakiegokolwiek intellisense. Musimy pamiętać każdą z metod i parametrów. Oczywiście prostota frameworku pozwala nieznacznie przełknąć tą niedogodność. Następny problem również zahacza o dynamiczność. Brak klas reprezentujących tabele, powoduje to iż jakakolwiek zmiana w bazie (zmiana nazwy kolumny, usunięcie kolumny) nie spowoduje błędu kompilacji. Dowiemy się jednak dopiero podczas działania aplikacji albo wcale! Dlatego Simple.Data polecam do maksymalnie średnich projektów, by nie złapać się na tego typu niuanse. Co nie zmienia faktu, iż framework ma ogromne zastosowania i gorąco polecam do zapoznania się z nim! 

    porady programowanie

    Komentarze

    0 nowych
    mikolaj_s   14 #1 13.11.2012 14:37

    Wydaje mi się, że przy małej intensywności korzystania z danych lepsza byłaby baza obiektowa, np. db4o.
    A jaki obiekt zwraca zapytanie?

    djfoxer   18 #2 13.11.2012 15:18

    @mikolaj_s
    Zwracane są obiekty typu simple.data.simplerecord, dynamiczne. Można rzutować na własny, dowolny typ mający odpowiednie pola (dla danych z bazy można oczywiście nadawać aliasy) http://simplefx.org/simpledata/docs/pages/Retrieve/WorkingWithPOCOs.htm. Całość robiona jest z "automatu".

    Co do db4o. Nie znałem tego wcześniej, ale we wpisie przedstawiłem odwrotny punkt. nie wychodzimy od bazy. Baza już jest (nie ma znaczenia jaka), a my musimy połączyć się z nią i na niej operować.

    tfl   8 #3 13.11.2012 16:50

    e tam, w linuxach od 9 lat.

    tfl   8 #4 13.11.2012 19:03

    mozna otwierac konserwe nozem, ale latwiej otwieraczem przeznaczonym do konserw. Mozna skladac zapytania typu create, ale latwiej w sql managment studio.

    djfoxer   18 #5 13.11.2012 19:09

    @RaveStar
    Trochę jednak więcej. Jeśli potrzebujesz masz tworzenie automatycznych joinów po kluczach obcych (automapping), testy jednostkowe, rewelacyjne rzutowanie bez zbędnych mapowań itp.
    Co do tworzenia tabel/widoków, to nie do tego służy ten framework, tak samo jak EF, czy nHibernate. Co z nowej tabeli utworzonej dynamicznie? Bardziej zaawansowane rzeczy i tak się robi po stronie procedur składowanych (raporty itp.) a na upartego można wywołać z Simple.Data procedurę SQL. Tylko po co? :D

    @tfl
    Dokładnie :)

    Autor edytował komentarz.
      #6 13.11.2012 23:58

    @tfl
    Wg mnie takie rozwiązanie ma kilka zalet, zwłaszcza jeżeli o .NET.

    Pierwszą zaletą jest uwspólnione API. Nie interesuje mnie, czy pod spodem jest baza, czy obiekty - podczas kodowania jest to dla mnie (wizualnie) przezroczyste. Oczywiście tylko dla pewnej klasy problemów o niskiej złożoności, gdzie nie musimy się zbytnio przejmować wydajnością i innymi problemami związanymi z bazą. Dla tych wolę myśleć obiektowo/biznesowo, a nie strukturalnie.

    Po drugie - plus głównie dla C# - świetnie wkomponowuje się w elastyczną składnię C#, pozwalając
    tworzyć tzw tasiemce, zamiast sterty bloków. To też nie zawsze jest zaletą, niektórzy powiedzą, że źle wpływa na czytelność kodu. Ale rozsądnie stosując IMHO ją poprawia, zwłaszcza, dla osób biegle się posługujących tasiemcami (będących logicznie ułożonym ciągiem), wyrażeniami lambda, czy LINQ. Jeżeli ktoś nie czuje się w takich konstrukcjach dobrze, nie uzna tego za zaletę (a poza .NETowcami pewnie jest to większość).

    iluzion   5 #7 14.11.2012 06:42

    Fajne. Przypomina mi nieco SQLAlchemy -- jedno z najlepszych rozwiązań tego typu. Tam też można wygenerować kod SQL z zapytań napisanych w znacznie przyjemniejszym języku, np.:

    >>> for name, in session.query(User.name).\
    ... filter(User.addresses.any(Address.email_address.like('%google%'))):
    ... print(name)

    sprowadza się do:

    SELECT users.name AS users_name
    FROM users
    WHERE EXISTS (SELECT 1
    FROM addresses
    WHERE users.id = addresses.user_id AND addresses.email_address LIKE ?)
    ('%google%',)

    djfoxer   18 #8 14.11.2012 10:29

    @RaveStar
    Nie read-only bo masz Insert/Update/Delete :P To jest framework, który podczepiasz pod projekt. W jakim projekcie tworzysz tabele? I gdzie ich używasz skoro są dynamiczne i nie wiesz z czego się składają? :)

    @iluzion
    Myślę, że autor Simple.Data wzorował się na SQLAlchemy. Kilka razy widziałem pytania w stylu "dlaczego nie ma czegoś takiego jak SQLAlchemy w .NET?" :)

    alucosoftware   7 #9 14.11.2012 11:25

    @djfoxer
    W rzeczy samej, prezentowany przez Ciebie framework jest rewelacyjny dla typowych zastosowań. Przyjrzę mu się dokładniej, ale już widzę ogromny potencjał w tym projekcie.

    Jak dobrze, że na łamach bloga można dowiedzieć się o takich perełkach. Świetny artykuł!

    djfoxer   18 #10 14.11.2012 14:13

    @alucosoftware
    Dzięki. Sam do niedawana nie wiedziałem o tej bibliotece. Domyślałem się, że jeśli jeszcze nie słyszałeś o Simple.Data to z pewnością przyda Ci się w pracy. Pozdrawiam.

    koneton   6 #11 14.11.2012 16:06

    Przejrzałem Twój wpis i na prawdę nie widzę specjalnych zalet tego rozwiązania w porównaniu z Hibernate (nie twierdzę, że jest gorsze). Używając Hibernate w aplikacji, która ma korzystać tylko z 4 tabel nie musisz mapować wszystkich istniejących, a tylko te, których będziesz używać. Jest jakiś inny powód dla którego lepiej używać Simple.Data zamiast nHibernate?

    djfoxer   18 #12 14.11.2012 16:26

    @koneton
    Aby korzystać z Simple.Data musisz zrobić:
    - dołączyć dllki do projektu
    - dodać connectionstring z bazą do configu
    Tylko tyle. A możliwości są ogromne.
    Mając np. nHibernate dodatkowo trzeba
    - porobić mapowania (faktycznie nie wszystkie, aczkolwiek z tym bywa różnie jak się robi to "automatycznie") w xml czy w klasach (fluent)
    - wygenerować klasy
    Miałem przypadek, że musiałem zrobić małą aplikację na urządzenia mobilne, która używała by bazy istniejącej. Jak się okazało wygenerowanie klas i mapowań było masakryczne. Baza była dość stara i ze względów optymalizacyjnych nie miała niektórych kluczy obcych, część rekordów miała różne typy łączące (np. klucz główny w tabeli było intem, a kolumna w innej tabeli z id do tej tabeli była decimalem) i kilka jeszcze niuansów które sprawiały, że wygenerowanie mapowań dla kilku tabel wyglądało tak, że trzeba było ręcznie wszystko stworzyć. W Simple.Data zasiadasz i masz wszystko bez generowania klas i mapowań. Idealne do małych i średnich projektów. Z Simple.Data masz szybki dostęp do bazy bez zbędnych konfiguracji. Oszczędzasz czas przy tego typu projektach.

    Autor edytował komentarz.
    iluzion   5 #13 14.11.2012 17:30

    @djfoxer

    "Myślę, że autor Simple.Data wzorował się na SQLAlchemy."

    Dotarłem do źródła inspiracji https://github.com/markrendle/Simple.Data ;) "Inspired by Ruby's ActiveRecord and DataMapper gems."


    "Kilka razy widziałem pytania w stylu "dlaczego nie ma czegoś takiego jak SQLAlchemy w .NET?" :)"

    Prawdopodobnie przyczyną był wspomniany dynamiczny system typów, który pojawił się wraz z DLR.

    "Simple.Data does this by using the dynamic features of .NET 4 to interpret method and property names at runtime and map them to your underlying data-store with a convention-based approach."

    Wygląda na to, że .NET jeszcze mile zaskoczy programistów dzięki DLR. Sądzę, że Simple.Data może być świetnym rozwiązaniem w połączeniu z IronPython lub IronRuby, bo pozwoli w pełni wykorzystać dynamiczną naturę tych języków.

    Autor edytował komentarz.
    siararadek   3 #14 14.11.2012 17:59

    A czy nie jest równie prosto wygenerować sobie klasy przez Entity Framework na podstawie istniejącej bazy danych? http://weblogs.asp.net/jgalloway/archive/2011/02/24/generating-ef-code-first-mod...

    Wtedy chociaż mamy statyczne typowanie, które sprawia, że nie mamy błędów w postaci literówek itd.

    alucosoftware   7 #15 14.11.2012 19:23

    @siararadek
    We wstępie jest o tym mowa (o wbudowanych generatorach ...) i uzasadnienie dla wyboru omawianej biblioteki.

    @iluzion
    Mam awersję do typów dynamicznych, ale w tym przypadku jestem w stanie zmienić swoje upodobania.

    Autor edytował komentarz.
    budda86   9 #16 14.11.2012 19:35

    Hm, wygląda bardzo fajnie, a jak z wydajnością? Czy przy każdym zapytaniu Books.FindAllById szuka tabeli, która pasuje nazwą? Co w przypadku, gdy mamy podobne nazwy? Jest jakieś cache'owanie wyników zapytań?

    Nie znam się za bardzo na .NET; czy dynamiczne typy to coś w stylu JavaScript? W sensie, że pobrany z bazy obiekt w czasie kompilacji jest nieznanego typu, i nie wiadomo, jakie ma pola? Jeśli tak, to nie za bardzo podoba mi się to rozwiązanie, statyczne typowanie jest dla mnie dużo bardziej eleganckie i przewidywalne.

    iluzion   5 #17 14.11.2012 21:07

    @budda86

    "dynamiczne typy to coś w stylu JavaScript?"

    Może być w stylu JavaScript, ale nie jest to zagadnienie związane z konkretnym językiem. W typach dynamicznych chodzi o śledzenie rodzajów obiektów (automatyczne przechowywanie informacji o typach) w czasie ich działania. Nie jest wymagana deklaracja. Kod pisze się z myślą o interfejsach, a nie o typach danych, dlatego można go stosować do całej gamy obiektów, np. na czymkolwiek po czym da się iterować. Polimorfizm pełną gębą :)

    "pobrany z bazy obiekt w czasie kompilacji jest nieznanego typu"

    Typy są znane, bo ustalane są automatycznie w momencie tworzenia obiektu.

    "jakie ma pola?"

    Znane. Choćby z tego względu, że IDE jest w stanie podpowiedzieć.

    Autor edytował komentarz.
    koneton   6 #18 15.11.2012 09:22

    @djfoxer
    Rozumiem, że użycie tego daje nam szybszy start w projekcie. Jednak co z jego utrzymaniem? Z mojego kilkunastoletniego doświadczenia w programowaniu/projektowaniu wynika, że większość mojej pracy (70%-80%) polega na poprawianiu istniejącej funkcjonalności i dodawaniu nowej a pisanie od zera stanowi małą część pracy. Czy aplikacje pisane przy użyciu Simple.Data da się tak łatwo utrzymywać i zarządzać jak w przy użyciu nHibernate? Jak jest z czytelnością kodu, jego modyfikacją? Jak wygląda wydajność w stosunku doi innych rozwiązań?

    djfoxer   18 #19 15.11.2012 13:25

    @koneton
    Oczywiście konserwacja to duży problem. W tym przypadku utrzymanie kodu może być trudniejsze niż w NH. Zobacz jednak, że Simple.Data nie jest przeznaczony do rozległych, dużych projektów (np. z Nancy http://nancyfx.org/). Co więcej, myślę, że z drugiej strony można pokusić się o trywialne rzutowanie na POCO. Dopiero zauważyłem, że autor biblioteki przedstawił sposób na powiązanie statycznych deklaracji z Simple.Data. Więcej: http://blog.markrendle.net/2012/10/12/howto-dial-up-the-static-on-simple-data/ . Czytelność kodu jest rewelacyjna, chociaż jest oto pojęcie względne dla każdego z nas zapewne. Temat wydajności. Hmm. Nie mogę nic obecnie powiedzieć, gdyż dane nie były olbrzymie. Zapewne jest gdzieś blisko za NH, ze względu na dynamiczność. Warto jednak powtórzyć, że Simple.Data nie jest zamiennikiem NH, to raczej biblioteka, która w kilku przypadkach będzie lepsza niż NH, czy EF.

    Autor edytował komentarz.
    djfoxer   18 #20 15.11.2012 13:26

    @budda86
    Jak pisałem dla koneton, zawsze możesz rzutować na POCO lub zrobićproxy o jakim pisze autor wtyczki: http://blog.markrendle.net/2012/10/12/howto-dial-up-the-static-on-simple-data .

    cinkibolek   5 #21 15.11.2012 15:39

    Zarąbista sprawa, czegoś takiego szukałem. Dzięki wielkie.

    iluzion   5 #22 18.11.2012 13:01

    @RaveStar

    Lub to: http://sqlkorma.com/

      #23 29.08.2013 08:03

    @iluzion , @budda86
    "Znane. Choćby z tego względu, że IDE jest w stanie podpowiedzieć."
    Nie jest w stanie, właśnie dlatego, że mamy do czynienia z typem dynamicznym. W praktyce typ dynamiczny to w rzeczywistości nakładka stosowania przez język C# po to, aby umożliwić w pełni dynamiczne typowanie.

    To co jest pod spodem wynika z implementacji wykonanej przez programistę. Może to być typ statyczny - w takim wypadku dodatkowy koszt wynikający z dynamizacji jest ponoszony raz, w momencie pierwszego odwołania do wartości typu dynamicznego. Na jego podstawie generowany jest potem już optymalny kod traktujący daną właściwość jak typ statyczny. Jednakże w przypadku kiedy nie mamy informacji o typach - a takim przypadkiem jest Simple.Data - typ dynamiczny z reguły ukrywa pod maską mechanizm wiązania nazw metod/właściwości opartych o hashmapy.

    W przypadku Simple.Data nie jest to jednak wielki ból, ponieważ sam framework jest bardzo prosty w konstrukcji i nie zawiera zbyt wielu warstw abstrakcji, przez co sam z siebie jest w stanie działać szybciej niż kolosy pokroju NHibernate czy EF (wciąż jednak wolniej niż inne mikro-frameworki konkurujące w ten samej kategorii np. Dapper czy OrmLite).

    Jeżeli o mnie chodzi polecam zapoznać się z F# Type Providers ( http://msdn.microsoft.com/en-us/library/hh156509.aspx ) - absolutnie rewolucyjne rozwiązanie, w chwili obecnej bez odpowienika w jakimkolwiek innym języku.

      #24 29.08.2013 08:05

    @iluzion , @budda86
    "Znane. Choćby z tego względu, że IDE jest w stanie podpowiedzieć."
    Nie jest w stanie, właśnie dlatego, że mamy do czynienia z typem dynamicznym. W praktyce typ dynamiczny to w rzeczywistości nakładka stosowania przez język C# po to, aby umożliwić w pełni dynamiczne typowanie.

    To co jest pod spodem wynika z implementacji wykonanej przez programistę. Może to być typ statyczny - w takim wypadku dodatkowy koszt wynikający z dynamizacji jest ponoszony raz, w momencie pierwszego odwołania do wartości typu dynamicznego. Na jego podstawie generowany jest potem już optymalny kod traktujący daną właściwość jak typ statyczny. Jednakże w przypadku kiedy nie mamy informacji o typach - a takim przypadkiem jest Simple.Data - typ dynamiczny z reguły ukrywa pod maską mechanizm wiązania nazw metod/właściwości opartych o hashmapy.

    W przypadku Simple.Data nie jest to jednak wielki ból, ponieważ sam framework jest bardzo prosty w konstrukcji i nie zawiera zbyt wielu warstw abstrakcji, przez co sam z siebie jest w stanie działać szybciej niż kolosy pokroju NHibernate czy EF (wciąż jednak wolniej niż inne mikro-frameworki konkurujące w ten samej kategorii np. Dapper czy OrmLite).

    Jeżeli o mnie chodzi polecam zapoznać się z F# Type Providers ( http://msdn.microsoft.com/en-us/library/hh156509.aspx ) - absolutnie rewolucyjne rozwiązanie, w chwili obecnej bez odpowienika w jakimkolwiek innym języku.

      #25 04.09.2013 21:56

    Ten jest fajny i szybki: https://github.com/sapiens/SqlFu

    Poza tym na samym dole można znaleźć listę z innymi tego typu micro-ormami. :)