Ich bin neu im Dapper Micro ORM. Bisher kann ich es für einfache ORM-bezogene Dinge verwenden, aber ich kann die Namen der Datenbankspalten nicht den Klasseneigenschaften zuordnen.
Zum Beispiel habe ich die folgende Datenbanktabelle:
Table Name: Person
person_id int
first_name varchar(50)
last_name varchar(50)
und ich habe eine Klasse namens Person:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Bitte beachten Sie, dass sich meine Spaltennamen in der Tabelle vom Eigenschaftsnamen der Klasse unterscheiden, der ich die Daten zuordnen möchte, die ich aus dem Abfrageergebnis erhalten habe.
var sql = @"select top 1 PersonId,FirstName,LastName from Person";
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(sql).ToList();
return person;
}
Der obige Code funktioniert nicht, da die Spaltennamen nicht mit den Eigenschaften des Objekts (Person) übereinstimmen. Kann ich in diesem Szenario in Dapper etwas tun, um person_id => PersonId
die Spaltennamen mit Objekteigenschaften manuell zuzuordnen (z. B. )?
Antworten:
Das funktioniert gut:
Dapper hat keine Funktion, mit der Sie ein Spaltenattribut angeben können. Ich bin nicht dagegen, Unterstützung dafür hinzuzufügen, vorausgesetzt, wir ziehen die Abhängigkeit nicht ein.
quelle
Dapper unterstützt jetzt benutzerdefinierte Zuordnungen von Spalten zu Eigenschaften. Dies geschieht über die ITypeMap- Schnittstelle. Dapper stellt eine CustomPropertyTypeMap- Klasse bereit, die den größten Teil dieser Arbeit erledigen kann. Beispielsweise:
Und das Modell:
Es ist wichtig zu beachten, dass die Implementierung von CustomPropertyTypeMap erfordert, dass das Attribut vorhanden ist und mit einem der Spaltennamen übereinstimmt, da sonst die Eigenschaft nicht zugeordnet wird. Die DefaultTypeMap- Klasse bietet die Standardfunktionalität und kann genutzt werden, um dieses Verhalten zu ändern:
Auf diese Weise wird es einfach, einen benutzerdefinierten Typ-Mapper zu erstellen, der die Attribute automatisch verwendet, wenn sie vorhanden sind, ansonsten aber auf das Standardverhalten zurückgreift:
Das heißt, wir können jetzt problemlos Typen unterstützen, für die eine Zuordnung erforderlich ist, indem wir Attribute verwenden:
Hier ist eine Zusammenfassung des vollständigen Quellcodes .
quelle
Für einige Zeit sollte Folgendes funktionieren:
quelle
MatchNamesWithUnderscores
Option zu entfernen . Wenn wir die Konfigurations-API überarbeiten würden, würde ich das Mitglied bestenfallsMatchNamesWithUnderscores
an Ort und Stelle belassen (was im Idealfall immer noch funktioniert) und einen[Obsolete]
Marker hinzufügen , um Personen auf die neue API zu verweisen.Hier ist eine einfache Lösung, für die keine Attribute erforderlich sind, sodass Sie den Infrastrukturcode aus Ihren POCOs heraushalten können.
Dies ist eine Klasse, die sich mit den Zuordnungen befasst. Ein Wörterbuch würde funktionieren, wenn Sie alle Spalten zugeordnet hätten. Mit dieser Klasse können Sie jedoch nur die Unterschiede angeben. Darüber hinaus enthält es umgekehrte Zuordnungen, sodass Sie das Feld aus der Spalte und die Spalte aus dem Feld abrufen können. Dies kann hilfreich sein, wenn Sie beispielsweise SQL-Anweisungen generieren.
Richten Sie das ColumnMap-Objekt ein und weisen Sie Dapper an, das Mapping zu verwenden.
quelle
Ich mache folgendes mit Dynamic und LINQ:
quelle
Eine einfache Möglichkeit, dies zu erreichen, besteht darin, nur Aliase für die Spalten in Ihrer Abfrage zu verwenden. Wenn Ihre Datenbankspalte
PERSON_ID
und die Eigenschaft Ihres Objekts istID
, können Sie dies einfachselect PERSON_ID as Id ...
in Ihrer Abfrage tun, und Dapper wird es wie erwartet abholen.quelle
Entnommen aus den Dapper-Tests, die derzeit auf Dapper 1.42 laufen.
Hilfsklasse, um den Namen aus dem Description-Attribut zu entfernen (ich persönlich habe Column wie das @ kalebs-Beispiel verwendet)
Klasse
quelle
GetDescriptionFromAttribute
zureturn (attrib?.Description ?? member.Name).ToLower();
und hinzugefügt ,.ToLower()
umcolumnName
in der Karte nicht case sensitive sein sollte.Das Spielen mit dem Mapping ist eine Grenzlinie, die sich in echtes ORM-Land bewegt. Anstatt damit zu kämpfen und Dapper in seiner wirklich einfachen (schnellen) Form zu halten, ändern Sie Ihr SQL einfach leicht wie folgt:
quelle
Führen Sie diesen Code für jede Ihrer Poco-Klassen aus, bevor Sie die Verbindung zu Ihrer Datenbank öffnen:
Fügen Sie dann die Datenanmerkungen wie folgt zu Ihren Poco-Klassen hinzu:
Danach sind Sie fertig. Machen Sie einfach einen Abfrageanruf, so etwas wie:
quelle
Wenn Sie .NET 4.5.1 oder höher verwenden, überprüfen Sie Dapper.FluentColumnMapping für die Zuordnung des LINQ-Stils. Damit können Sie die Datenbankzuordnung vollständig von Ihrem Modell trennen (keine Anmerkungen erforderlich).
quelle
Dies ist ein Huckepack von anderen Antworten. Es ist nur ein Gedanke, den ich hatte, um die Abfragezeichenfolgen zu verwalten.
Person.cs
API-Methode
quelle
Für alle, die Dapper 1.12 verwenden, müssen Sie Folgendes tun, um dies zu erreichen:
und kommentiere es aus.
quelle
Die Lösung von Kaleb Pederson hat bei mir funktioniert. Ich habe den ColumnAttributeTypeMapper aktualisiert, um ein benutzerdefiniertes Attribut zuzulassen (für das zwei verschiedene Zuordnungen für dasselbe Domänenobjekt erforderlich waren), und die Eigenschaften aktualisiert, um private Setter in Fällen zuzulassen, in denen ein Feld abgeleitet werden musste und die Typen unterschiedlich waren.
quelle
Ich weiß, dass dies ein relativ alter Thread ist, aber ich dachte, ich würde das, was ich getan habe, da draußen werfen.
Ich wollte, dass die Attributzuordnung global funktioniert. Entweder stimmen Sie mit dem Eigenschaftsnamen überein (auch bekannt als Standard), oder Sie stimmen mit einem Spaltenattribut für die Klasseneigenschaft überein. Ich wollte dies auch nicht für jede einzelne Klasse einrichten müssen, der ich zugeordnet war. Aus diesem Grund habe ich eine DapperStart-Klasse erstellt, die ich beim Start der App aufrufe:
Ziemlich einfach. Ich bin mir nicht sicher, auf welche Probleme ich noch stoßen werde, als ich das gerade geschrieben habe, aber es funktioniert.
quelle
CreateChatRequestResponse
sei denn, es wird ersetzt,T
wie dies alle Entitätsobjekte durchlaufen würde. Bitte korrigieren Sie mich, wenn ich falsch liege.Die einfache Lösung für das Problem, das Kaleb zu lösen versucht, besteht darin, nur den Eigenschaftsnamen zu akzeptieren, wenn das Spaltenattribut nicht vorhanden ist:
quelle