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

25voto

Oliver Points 2004

Extrait des tests de Dapper actuellement sur Dapper 1.42.

// mapping personnalisé
var map = new CustomPropertyTypeMap(
                 typeof(TypeWithMapping), 
                 (type, columnName) => 
                        type.GetProperties().FirstOrDefault(prop => 
                                GetDescriptionFromAttribute(prop) == columnName));
Dapper.SqlMapper.SetTypeMap(typeof(TypeWithMapping), map);

Classe utilitaire pour récupérer le nom de l'attribut Description (personnellement j'ai utilisé Column comme dans l'exemple de @kaleb)

static string GetDescriptionFromAttribute(MemberInfo member)
{
   if (member == null) return null;

   var attrib = (DescriptionAttribute) Attribute.GetCustomAttribute(
                         member,
                         typeof(DescriptionAttribute), false);

   return attrib == null ? null : attrib.Description;
}

Classe

public class TypeWithMapping
{
   [Description("B")]
   public string A { get; set; }

   [Description("A")]
   public string B { get; set; }
}

24voto

Brad Points 735

Un moyen simple d'y parvenir est simplement d'utiliser des alias sur les colonnes dans votre requête.

Si la colonne de votre base de données est PERSON_ID et que la propriété de votre objet est ID, vous pouvez simplement faire

sélectionnez PERSON_ID as Id ...

dans votre requête et Dapper le détectera comme prévu.

18voto

JedatKinports Points 2155

Avant d'ouvrir la connexion à votre base de données, exécutez ce code pour chacune de vos classes poco :

// Section
SqlMapper.SetTypeMap(typeof(Section), new CustomPropertyTypeMap(
    typeof(Section), (type, columnName) => type.GetProperties().FirstOrDefault(prop =>
    prop.GetCustomAttributes(false).OfType().Any(attr => attr.Name == columnName))));

Ensuite, ajoutez les annotations de données à vos classes poco comme ceci :

public class Section
{
    [Column("db_column_name1")] // Note latérale : si vous créez des alias, ils correspondraient à ceci.
    public int Id { get; set; }
    [Column("db_column_name2")]
    public string Title { get; set; }
}

Après cela, vous êtes prêt. Il vous suffit de faire un appel de requête, quelque chose comme :

using (var sqlConnection = new SqlConnection("votre_chaîne_de_connexion"))
{
    var sqlStatement = "SELECT " +
                "db_column_name1, " +
                "db_column_name2 " +
                "FROM your_table";

    return sqlConnection.Query

15voto

mxmissile Points 4179

Trifouiller avec le mapping frôle la limite de passer dans le véritable monde de l'ORM. Au lieu de lutter contre cela et de garder Dapper dans sa forme simple (rapide) d'origine, il suffit de modifier légèrement votre SQL comme ceci :

var sql = @"select top 1 person_id as PersonId,FirstName,LastName from Person";

8voto

mamuesstack Points 1059

Si vous utilisez .NET 4.5.1 ou une version supérieure, consultez Dapper.FluentColumnMapping pour mapper le style LINQ. Cela vous permet de séparer complètement le mapping de la base de données de votre modèle (pas besoin d'annotations)

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