Je suis nouveau sur le micro ORM Dapper. Jusqu'à présent, je suis capable de l'utiliser pour des trucs simples liés à l'ORM, mais je ne suis pas en mesure de mapper les noms de colonne de la base de données avec les propriétés de classe.
Par exemple, j'ai la table de base de données suivante:
Table Name: Person
person_id int
first_name varchar(50)
last_name varchar(50)
et j'ai une classe appelée Person:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { 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 à partir du résultat de la requête.
var sql = @"select top 1 PersonId,FirstName,LastName from Person";
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(sql).ToList();
return person;
}
Le code ci-dessus ne fonctionnera pas car les noms de colonne ne correspondent pas aux propriétés (Person) de l'objet. Dans ce scénario, y a-t-il quelque chose que je puisse faire dans Dapper pour mapper manuellement (par exemple person_id => PersonId
) les noms de colonnes avec les propriétés d'objet?
Réponses:
Cela fonctionne bien:
Dapper n'a aucune fonctionnalité qui vous permet de spécifier un attribut de colonne , je ne suis pas contre l'ajout de la prise en charge de celui-ci, à condition que nous ne tirions pas dans la dépendance.
la source
Dapper prend désormais en charge la colonne personnalisée vers les mappeurs de propriétés. Il le fait via l' interface ITypeMap . Une classe CustomPropertyTypeMap est fournie par Dapper qui peut effectuer la plupart de ce travail. Par exemple:
Et le modèle:
Il est important de noter que l'implémentation de CustomPropertyTypeMap nécessite que l'attribut existe et corresponde à l'un des noms de colonne ou la propriété ne sera pas mappée. La classe DefaultTypeMap fournit la fonctionnalité standard et peut être exploitée pour modifier ce comportement:
Et avec cela en place, il devient facile de créer un mappeur de type personnalisé qui utilisera automatiquement les attributs s'ils sont présents, mais qui reviendra autrement au comportement standard:
Cela signifie que nous pouvons désormais facilement prendre en charge les types qui nécessitent une carte à l'aide d'attributs:
Voici un résumé du code source complet .
la source
Pendant un certain temps, les éléments suivants devraient fonctionner:
la source
MatchNamesWithUnderscores
option. Au mieux , si nous refactorions l'API de configuration, je laisserais leMatchNamesWithUnderscores
membre en place (cela fonctionne toujours, idéalement) et ajouterais un[Obsolete]
marqueur pour diriger les gens vers la nouvelle API.Voici une solution simple qui ne nécessite pas d'attributs vous permettant de garder le code d'infrastructure hors de vos POCO.
C'est une classe pour gérer les mappages. Un dictionnaire fonctionnerait si vous mappiez toutes les colonnes, mais cette classe vous permet de spécifier uniquement les différences. En outre, il inclut des cartes inversées afin que vous puissiez obtenir le champ de la colonne et la colonne du champ, ce qui peut être utile lors de tâches telles que la génération d'instructions sql.
Configurez l'objet ColumnMap et indiquez à Dapper d'utiliser le mappage.
la source
Je fais ce qui suit en utilisant dynamic et LINQ:
la source
Un moyen simple d'y parvenir est d'utiliser simplement des alias sur les colonnes de votre requête. Si votre colonne de base de données est
PERSON_ID
et que la propriété de votre objet est,ID
vous pouvez simplement le faireselect PERSON_ID as Id ...
dans votre requête et Dapper la récupérera comme prévu.la source
Tiré des tests Dapper qui sont actuellement sur Dapper 1.42.
Classe d'assistance pour obtenir le nom de l'attribut Description (j'ai personnellement utilisé Column comme l'exemple @kalebs)
Classe
la source
GetDescriptionFromAttribute
àreturn (attrib?.Description ?? member.Name).ToLower();
et ajouté.ToLower()
àcolumnName
la carte, il ne devrait pas être sensible à la casse.Jouer avec la cartographie est à la limite du déplacement vers de véritables terres ORM. Au lieu de se battre avec lui et de garder Dapper dans sa vraie forme simple (rapide), modifiez simplement votre SQL légèrement comme ceci:
la source
Avant d'ouvrir la connexion à votre base de données, exécutez ce morceau de code pour chacune de vos classes poco:
Ajoutez ensuite les annotations de données à vos classes poco comme ceci:
Après cela, vous êtes prêt. Faites simplement un appel de requête, quelque chose comme:
la source
Si vous utilisez .NET 4.5.1 ou une version ultérieure, vérifiez Dapper.FluentColumnMapping pour mapper le style LINQ. Il vous permet de séparer complètement le mappage db de votre modèle (pas besoin d'annotations)
la source
C'est le soutien d'autres réponses. C'est juste une pensée que j'avais pour gérer les chaînes de requête.
Person.cs
Méthode API
la source
pour tous ceux qui utilisent Dapper 1.12, voici ce que vous devez faire pour y parvenir:
et commentez-le.
la source
La solution de Kaleb Pederson a fonctionné pour moi. J'ai mis à jour le ColumnAttributeTypeMapper pour autoriser un attribut personnalisé (exigeant deux mappages différents sur le même objet de domaine) et mis à jour les propriétés pour autoriser les setters privés dans les cas où un champ devait être dérivé et les types différaient.
la source
Je sais que c'est un fil de discussion relativement ancien, mais j'ai pensé jeter ce que j'ai fait là-bas.
Je voulais que le mappage d'attributs fonctionne globalement. Soit vous faites correspondre le nom de la propriété (aka default), soit vous faites correspondre un attribut de colonne sur la propriété de classe. Je ne voulais pas non plus avoir à configurer cela pour chaque classe à laquelle je mappais. En tant que tel, j'ai créé une classe DapperStart que j'appelle au démarrage de l'application:
Assez simple. Je ne sais pas quels problèmes je vais encore rencontrer car je viens d'écrire ceci, mais cela fonctionne.
la source
CreateChatRequestResponse
soit remplacé parT
comment cela itérerait à travers tous les objets Entity. S'il vous plait corrigez moi si je me trompe.La solution simple au problème que Kaleb essaie de résoudre est simplement d'accepter le nom de la propriété si l'attribut de colonne n'existe pas:
la source