194 votes

Mappez manuellement les noms de colonnes avec les propriétés de classe

Je suis nouveau dans le micro ORM Dapper. Jusqu'à présent, je suis capable de l'utiliser pour des tâches simples liées à l'ORM mais je ne suis pas capable de mapper les noms des colonnes de la base de données avec les propriétés de la classe.

Par exemple, j'ai la table de base de données suivante :

Nom de la table : Personne
person_id  int
first_name varchar(50)
last_name  varchar(50)

et j'ai une classe appelée Personne :

public class Personne 
{
    public int PersonneId { get; set; }
    public string Prenom { get; set; }
    public string Nom { get; set; }
}

Veuillez noter que les noms de mes colonnes dans la table sont différents du nom de propriété de la classe à laquelle j'essaie de mapper les données que j'ai obtenues du résultat de la requête.

var sql = @"select top 1 PersonneId,Prenom,Nom from Personne";
using (var conn = ConnectionFactory.GetConnection())
{
    var personne = conn.Query(sql).ToList();
    return personne;
}

Le code ci-dessus ne fonctionnera pas car les noms des colonnes ne correspondent pas aux propriétés de l'objet (Personne). Dans ce scénario, y a-t-il quelque chose que je peux faire dans Dapper pour mapper manuellement (par exemple person_id => PersonneId) les noms des colonnes avec les propriétés de l'objet ?

0 votes

1voto

Matt M Points 151

Je sais que c'est un fil de discussion relativement ancien, mais je voulais partager ce que j'ai fait.

Je voulais que le mappage des attributs fonctionne de manière globale. Soit vous faites correspondre le nom de la propriété (alias par défaut) soit vous faites correspondre un attribut de colonne sur la propriété de la classe. Je ne voulais pas non plus devoir configurer cela pour chaque classe à laquelle je faisais correspondre. J'ai donc créé une classe DapperStart que j'appelle au démarrage de l'application :

public static class DapperStart
{
    public static void Bootstrap()
    {
        Dapper.SqlMapper.TypeMapProvider = type =>
        {
            return new CustomPropertyTypeMap(typeof(CreateChatRequestResponse),
                (t, columnName) => t.GetProperties().FirstOrDefault(prop =>
                    {
                        return prop.Name == columnName || prop.GetCustomAttributes(false).OfType()
                                   .Any(attr => attr.Name == columnName);
                    }
                ));
        };
    }
}

Plutôt simple. Je ne suis pas sûr des problèmes auxquels je pourrais être confronté pour le moment car je viens juste d'écrire cela, mais ça marche.

1voto

Notez que la correspondance d'objets de Dapper n'est pas sensible à la casse, vous pouvez donc nommer vos propriétés comme ceci :

public class Person 
{
    public int Person_Id { get; set; }
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
}

Ou conservez la classe Person et utilisez un PersonMap :

  public class PersonMap 
        {
            public int Person_Id { get; set; }
            public string First_Name { get; set; }
            public string Last_Name { get; set; }
            public Person Map(){
              return new Person{
                PersonId = Person_Id,
                FirstName = First_Name,
                LastName = Last_Name
               }               
            }
        }

Ensuite, dans le résultat de la requête :

var person = conn.Query(sql).Select(x=>x.Map()).ToList();

0voto

GennadyGS Points 31

Je suggérerais une solution similaire à celle de @liorafar, mais basée sur des dictionnaires plutôt que sur des dynamiques :

using var conn = ConnectionFactory.GetConnection();
var person = conn.Query(sql)
    .Cast>()
    .Select(record =>
        new Person
        {
            PersonId = (int)record["person_id"],
            FirstName = (string)record["first_name"],
            LastName = (string)record["last_name"],
        })
    .ToList();

À mon avis, cette option est plus conviviale pour le refactoring : par exemple, vous pouvez déclarer les noms de colonnes comme des constantes ou les lire depuis une configuration. De plus, contrairement à la solution avec des dynamiques, elle permet d'extraire la méthode de transformation du dictionnaire en instance de modèle (instance de type Person) dans une méthode séparée, ce qui est particulièrement utile pour les modèles avec de nombreux champs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X