Aller au contenu

Une courte présentation de Dapper.Net

·427 mots·3 mins
Sommaire

Dapper est un wrapper pour le framework .Net qui étend, par des extensions de méthodes, les fonctionnalités présentes dans le namespace System.Data.Client pour la connexion à une base de données.

En gros, on reste avec du code dans lequel on ouvre gentiment ses connexions et dans lequel on fait ses requêtes, à l’ancienne, mais en ajoutant un ensemble de fonctions ‘achement utiles, comme par exemple Query<T> qui va faire correspondre les colonnes de la requête avec les champs d’une classe.

On est un niveau plus bas qu’un ORM, mais un niveau plus haut qu’un client ADO.Net classique. On garde donc la main sur la construction de nos requêtes… Ce qui a ses avantages et inconvénients :)

En plus de cela, il existe le projet Dapper.Contrib, dans lequel on trouve la classe SqlBuilder, qui permet d’améliorer la construction des requêtes. Son fonctionnement est un chouia touchy la première fois, mais fonctionne particulièrement bien au second tour :-) Tout fonctionne en fait sur base de clauses et de templates.

  1. On définit une requête de base (Select * From Table /**where**/", ci-dessous), que l’on donne à manger à un template,
  2. Les chaînes de caractères (ici, /**where**/) sont ensuite transformées en fonction de clauses passées en paramètres:
using Dapper;

SqlBuilder builder = new SqlBuilder();

var template = builder.AddTemplate(
    @"Select * From Table /**where**/"
);

builder.Where("NodeAttribute.[Key] = 'Route'");
builder.Where("NodeAttributeValue.NodeId = @nodeId", new { nodeId = nodeId });

using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["My_Connection_String"].ConnectionString))
{
    var result = sqlConnection.Query<string>(
        template.RawSql,
        template.Parameters
    );
}

En résumé
#

  1. On crée un SqlBuilder et un template via la méthode AddTemplate.
  2. Puis on applique un ensemble de clauses via la méthode Where, sur notre nouveau builder.

Le résultat sera ensuite généré en ouvrant une connection classique grâce à une nouvelle instance de SqlConnection, ouverte grâce à une chaîne de connexion disponible dans le ConfigurationManager.

Finalement, on utilisera la méthode Query<T> dont on parlait ci-dessus pour récupérer tous les enregistrements préents dans la base de données et qui répondent à cette requête, en lui passant le template brut et les clauses en paramètres. Cf. ce bloc-ci en particulier:

var result = sqlConnection.Query<string>(
    template.RawSql,
    template.Parameters
);

En conclusion
#

Cela demande un peu de réflexion par rapport à une connexion classique, un peu plus de travail qu’un (micro-)ORM, mais cela permet surtout d’avoir un contrôle énorme sur les requêtes exécutées.

Après avoir essayé plusieurs ORM pour le framework .Net, j’en reviens toujours à cette solution-ci. En terme de performances, c’est sans équivalent (bien que je ne doute pas que le contraire existe :)).

Sources: