Saya baru mengenal ORM mikro Dapper. Sejauh ini saya dapat menggunakannya untuk hal-hal sederhana yang berhubungan dengan ORM, tetapi saya tidak dapat memetakan nama kolom basis data dengan properti kelas.
Sebagai contoh, saya memiliki tabel database berikut:
Table Name: Person
person_id int
first_name varchar(50)
last_name varchar(50)
dan saya memiliki kelas yang disebut Person:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Harap perhatikan bahwa nama kolom saya di tabel berbeda dari nama properti kelas yang saya coba petakan data yang saya dapatkan dari hasil kueri.
var sql = @"select top 1 PersonId,FirstName,LastName from Person";
using (var conn = ConnectionFactory.GetConnection())
{
var person = conn.Query<Person>(sql).ToList();
return person;
}
Kode di atas tidak akan berfungsi karena nama kolom tidak cocok dengan properti (Orang) objek. Dalam skenario ini, apakah ada yang bisa saya lakukan di Dapper untuk memetakan secara manual (misalnya person_id => PersonId
) nama kolom dengan properti objek?
Jawaban:
Ini berfungsi dengan baik:
Dapper tidak memiliki fasilitas yang memungkinkan Anda menentukan Atribut Kolom , saya tidak menentang menambahkan dukungan untuk itu, asalkan kami tidak menarik ketergantungan.
sumber
Dapper sekarang mendukung kolom khusus ke pemetaan properti. Ia melakukannya melalui antarmuka ITypeMap . Kelas CustomPropertyTypeMap disediakan oleh Dapper yang dapat melakukan sebagian besar pekerjaan ini. Sebagai contoh:
Dan modelnya:
Penting untuk dicatat bahwa implementasi CustomPropertyTypeMap mensyaratkan bahwa atribut ada dan cocok dengan salah satu nama kolom atau properti tidak akan dipetakan. Kelas DefaultTypeMap menyediakan fungsionalitas standar dan dapat dimanfaatkan untuk mengubah perilaku ini:
Dan dengan itu, mudah untuk membuat mapper tipe khusus yang secara otomatis akan menggunakan atribut jika mereka ada tetapi sebaliknya akan kembali ke perilaku standar:
Itu berarti kita sekarang dapat dengan mudah mendukung tipe yang memerlukan peta menggunakan atribut:
Berikut adalah Intisari ke kode sumber lengkap .
sumber
Untuk beberapa waktu, berikut ini akan berfungsi:
sumber
MatchNamesWithUnderscores
opsi. Paling-paling , jika kami refactored API konfigurasi, saya akan meninggalkanMatchNamesWithUnderscores
anggota di tempatnya (yang masih berfungsi, idealnya) dan menambahkan[Obsolete]
penanda untuk mengarahkan orang ke API baru.Berikut ini adalah solusi sederhana yang tidak memerlukan atribut yang memungkinkan Anda untuk menjaga kode infrastruktur dari POCO Anda.
Ini adalah kelas untuk berurusan dengan pemetaan. Kamus akan berfungsi jika Anda memetakan semua kolom, tetapi kelas ini memungkinkan Anda menentukan hanya perbedaannya. Selain itu, ini termasuk peta terbalik sehingga Anda bisa mendapatkan bidang dari kolom dan kolom dari bidang, yang dapat berguna saat melakukan hal-hal seperti menghasilkan pernyataan sql.
Setup objek ColumnMap dan beri tahu Dapper untuk menggunakan pemetaan.
sumber
Saya melakukan hal berikut ini menggunakan dynamic dan LINQ:
sumber
Cara mudah untuk mencapai ini adalah dengan hanya menggunakan alias pada kolom dalam permintaan Anda. Jika kolom basis data Anda
PERSON_ID
dan proprty objek Anda,ID
Anda dapat melakukannyaselect PERSON_ID as Id ...
di kueri dan Dapper akan mengambilnya seperti yang diharapkan.sumber
Diambil dari Tes Dapper yang saat ini ada di Dapper 1.42.
Kelas pembantu untuk mendapatkan nama dari atribut Deskripsi (Saya pribadi telah menggunakan Kolom seperti contoh @kalebs)
Kelas
sumber
GetDescriptionFromAttribute
kereturn (attrib?.Description ?? member.Name).ToLower();
dan ditambahkan.ToLower()
kecolumnName
dalam peta yang seharusnya tidak peka huruf besar-kecil.Messing with mapping adalah pemindahan batas ke tanah ORM nyata. Alih-alih berkelahi dengannya dan menjaga Dapper dalam bentuknya yang sederhana (cepat), modifikasi SQL Anda sedikit seperti ini:
sumber
Sebelum Anda membuka koneksi ke database Anda, jalankan kode ini untuk setiap kelas poco Anda:
Kemudian tambahkan anotasi data ke kelas poco Anda seperti ini:
Setelah itu, Anda siap. Buat saja panggilan permintaan, sesuatu seperti:
sumber
Jika Anda menggunakan .NET 4.5.1 atau checkout Dapper.FluentColumnMapping yang lebih tinggi untuk memetakan gaya LINQ. Ini memungkinkan Anda sepenuhnya memisahkan pemetaan db dari model Anda (tidak perlu penjelasan)
sumber
Ini celengan mundur dari jawaban lain. Itu hanya pemikiran yang saya miliki untuk mengelola string kueri.
Person.cs
Metode API
sumber
untuk Anda semua yang menggunakan Dapper 1.12, Inilah yang perlu Anda lakukan untuk menyelesaikan ini:
dan berkomentar.
sumber
Solusi Kaleb Pederson bekerja untuk saya. Saya memperbarui ColumnAttributeTypeMapper untuk memungkinkan atribut khusus (memiliki persyaratan untuk dua pemetaan berbeda pada objek domain yang sama) dan memperbarui properti untuk memungkinkan setter pribadi dalam kasus di mana bidang perlu diturunkan dan jenisnya berbeda.
sumber
Saya tahu ini adalah utas yang relatif lama, tetapi saya pikir saya akan membuang apa yang saya lakukan di luar sana.
Saya ingin pemetaan atribut berfungsi secara global. Entah Anda cocok dengan nama properti (alias default) atau Anda cocok dengan atribut kolom pada properti kelas. Saya juga tidak mau harus mengatur ini untuk setiap kelas yang saya pemetaan. Karena itu, saya membuat kelas DapperStart yang saya gunakan saat memulai aplikasi:
Cukup mudah. Tidak yakin masalah apa yang akan saya temui karena saya baru saja menulis ini, tetapi berhasil.
sumber
CreateChatRequestResponse
digantikan olehT
bagaimana ini akan beralih melalui semua objek Entity. Tolong koreksi saya jika saya salah.Solusi sederhana untuk masalah yang Kaleb coba selesaikan adalah hanya menerima nama properti jika atribut kolom tidak ada:
sumber