Dapper – Czy mniej znaczy więcej?

D

W tym wpisie chciałbym poruszyć temat biblioteki Dapper. Będzie to krótka zajawka pokazująca sposób użycia i to, jak niskim nakładem pracy można zacząć używać Dapper’a. Sami oceńcie.

Jeśli tekst Cię nie interesuje, możesz od razu przejść do repozytorium z kodem gdzie umieściłem mały dotnetowy projekt, napisany specjalnie aby zaprezentować działanie biblioteki Dapper.

Repo TUTAJ

Czytając ten post natrafisz też na opis niektórych elementów tego projektu. Zamierzam sukcesywnie dodawać przykłady użycia różnych składowych Dappera, więc projekt się rozrośnie.

Nie będę się dużo rozpisywał na temat ORMów. Jeśli jesteś programistą .NET, bez wątpienia znasz, a przynajmniej obiły Ci się o uszy, takie nazwy jak Entity Framework od Microsoftu lub nHibernate od Open-Source’u 😉 .

Na stronie projektu Dapper można przeczytać…

Dapper is a simple object mapper for .NET and owns the title of King of Micro ORM in terms of speed and is virtually as fast as using a raw ADO.NET data reader.

Zatem widać, że twórcy biblioteki (StackOverflow) stworzyli ją właśnie w celu optymalizacji zapytań i czasu dostępu do danych. Odczyt danych w porównaniu do użycia innych ORM jest dużo szybszy. Oprócz tego użycie biblioteki we własnym kodzie jest banalnie proste, a sama biblioteka posiada również kilka ciekawych dodatków, ale o tym kiedy indziej.

Przykłady użycia Dapper

Najbardziej proste przykłady użycia biblioteki Dapper. Prawie z dokumentacji. Powiedzmy że pracujemy na jakimś typie eventu.

…argumenty jakie są podawane umieściłem obok metod dla lepszego zrozumienia przykładu…

…metody są generyczne, a typ na których operują to klasa Event

public class Event
{
    public Guid AggregateId { get; set; }
    public byte[] Data { get; set; }
    public long SequenceNumber { get; set; }
    public int Version { get; set; }
}

a więc…

Select
string query = @"SELECT * FROM public.""Events"";";

public IEnumerable<EType> DapperQuery<EType>(string query)
{
    using (var connection = _connectionProvider.GetDbConnection())
    {
        var events = connection.Query<EType>(query).ToList();
        return events;
    }
}
Select
string query = @"SELECT * FROM public.""Events"" WHERE ""Version"" = @OrderDetailID;";

public EType DapperQueryFirstOrDefault<EType>(string query)
{
    using (var connection = _connectionProvider.GetDbConnection())
    {
        var singleEvent = connection.QueryFirstOrDefault<EType>(query, new { Version = 35 });
        return singleEvent;
    }
}
Insert
string query = @"INSERT INTO public.""Events"" (""AggregateId"", ""Data"", ""SequenceNumber"", ""Version"") VALUES (@AggregateId, @Data, @SequenceNumber, @Version);";

public int DapperExecuteInsert(string query, Event singleEvent)
{
    using (var connection = _connectionProvider.GetDbConnection())
    {
        var affectedRows = connection.Execute(query,
        new
        {
            AggregateId = singleEvent.AggregateId,
            Data = singleEvent.Data,
            SequenceNumber = singleEvent.SequenceNumber,
            Version = singleEvent.Version
        });

        return affectedRows;
    }
}

Przedstawiam tutaj te proste przykłady aby pokazać jak łatwe jest użycie tego biblioteki Dapper. Oczywiście im głebiej w las tym więcej implementacji do ogarnięcia, ale zapewniam, że w większości wypadków sprawa ogranicza się do użycia odpowiedniej metody Dappera i ew. przekazania/odebrania odpowiedniego typu obiektu.

Przykład dla tych metod znajduje się w klasie SimpleDapperExamples.

Jeśli chcesz się pobawić moim przykładem to…

Organizacja zabawy

W swoich przykładach używam bazy danych Postgresql w wersji 13.

  • relacyjna
  • open-source
  • stabilna i łatwa w użyciu

Więcej nie trzeba.

W związku z tym, przygotowałem docker-compose.yml za pomocą którego szybko postawicie serwer bazodanowy, jak i serwis do zarządzania tym serwerem bazodanowym pgadmin4strona projektu

Jeśli masz już swoją bazę danych u siebie, lub dostęp do jakiegoś serwera postgresql, droga wolna.

Poniżej listing mojego docker-compose.yml

version: "3"
services:
    postgres:
        image: postgres:13.1
        container_name: dapper-fun-postgres
        environment:
            POSTGRES_PASSWORD: Test1234 
        ports:
            - "5432:5432"
        networks:
            - postgres

    pgadmin:
        image: dpage/pgadmin4
        container_name: dapper-fun-pgadmin
        environment:
            PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-admin@pgadmin.org}
            PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
        ports:
            - "${PGADMIN_PORT:-5050}:80"
        networks:
            - postgres

networks:
    postgres:
        driver: bridge

volumes:
    postgres:
    pgadmin:
        driver: local

Teraz tylko wystarczy mieć zainstalowanego dockera i tool docker-compose. W terminalu lub cmd (co tam używasz) wpisać komendę…

docker-compose up

Reszta informacji w pliku README.md obok docker-compose.yml

Jeśli nie zmieniałeś/aś nic w connection stringu lub w kofiguracji w docker-compose.yml wystarczy, że uruchomisz webapi.

Natomiast aby przetestować przykładowe „strzały” do bazy wystarczy, że wywołasz odpowiednie metody kontrollera api.

Tyle, nie mniej nie więcej.

Jak widać niewiele trzeba aby zacząć używać biblioteki Dapper. Po prawdzie sprowadza się to do pobrania odpowiedniej paczki Nuget, utworzenia połączenia z bazą danych i używania extensions methods tej biblioteki.

Ale dlaczego akurat Dapper

Dlaczego Dapper? Bardzo proste:

  • Lekka biblioteka
  • Łatwa w użyciu
  • Super szybki odczyt danych, czyli zazwyczaj najczęstsza operacja
  • Bardzo ważne – masz kontrolę nad Twoim SQLem
  • Wersjonowanie bazy danych? Nie ma sprawy. Łatwo zrobić autoupdater w samym projekcie.

Koniec końców

Tak jak napisałem na początku. Ma to być tylko zajawka i mam nadzieję, że mi się udało, bo aby używać Dappera, na prawdę wiele nie trzeba.

Photo by Robin Pierre on Unsplash



Add comment

By Patryk

Autor serwisu

Patryk

Społecznościowe

Instagram

Instagram has returned empty data. Please authorize your Instagram account in the plugin settings .

Newsletter



Historycznie

Tagi