Saya baru saja mengganti ORM dan itu adalah tugas yang relatif menakutkan, karena logika kueri bocor di mana-mana. Jika saya pernah harus mengembangkan aplikasi baru, preferensi pribadi saya akan merangkum semua logika kueri (menggunakan ORM) untuk memastikannya untuk perubahan. Pola repositori cukup sulit untuk dikodekan dan dipelihara sehingga saya bertanya-tanya apakah ada pola lain untuk menyelesaikan masalah?
Saya dapat meramalkan posting tentang tidak menambahkan kompleksitas tambahan sebelum itu benar-benar diperlukan, menjadi lincah dll. Tapi saya hanya tertarik tentang pola yang ada memecahkan masalah yang sama dengan cara yang lebih sederhana.
Pikiran pertama saya adalah memiliki repositori tipe generik, yang saya tambahkan metode yang diperlukan untuk kelas repositori tipe spesifik melalui metode ekstensi, tetapi unit pengujian metode statis sangat menyakitkan. YAITU:
public static class PersonExtensions
{
public static IEnumerable<Person> GetRetiredPeople(this IRepository<Person> personRep)
{
// logic
}
}
sumber
Jawaban:
Pertama-tama: Repositori generik harus dianggap sebagai kelas dasar dan bukan implementasi lengkap. Ini akan membantu Anda mendapatkan metode CRUD yang umum. Tetapi Anda masih harus menerapkan metode kueri:
Kedua:
Jangan kembali
IQueryable
. Ini abstraksi yang bocor. Cobalah untuk mengimplementasikan antarmuka itu sendiri atau menggunakannya tanpa sepengetahuan penyedia db yang mendasarinya. Misalnya, setiap penyedia db memiliki API sendiri untuk memuat entitas dengan penuh semangat. Itu sebabnya ini adalah abstraksi yang bocor.Alternatif
Sebagai alternatif, Anda dapat menggunakan kueri (misalnya sebagaimana ditentukan oleh pola pemisahan Command / Query). CQS dijelaskan dalam wikipedia.
Anda pada dasarnya membuat kelas permintaan yang Anda panggil:
yang hebat dengan permintaan adalah bahwa Anda dapat menggunakan metode akses data yang berbeda untuk permintaan yang berbeda tanpa mengacaukan kode. Anda bisa misalnya menggunakan layanan web dalam satu, nhibernate di yang lain dan ADO.NET di ketiga.
Jika Anda tertarik pada implementasi .NET, baca artikel saya: http://blog.gauffin.org/2012/10/griffin-decoupled-the-queries/
sumber
YourProject.YourDomainModelName.Queries
itu akan mudah dinavigasi.Pertama yang saya katakan adalah ORM sudah menjadi abstraksi yang cukup besar atas database Anda. Beberapa ORM menyediakan pengikatan ke semua database relasional yang umum (NHibernate memiliki binding ke MSSQL, Oracle, MySQL, Postgress, dll.) Jadi membangun abstraksi baru di atasnya sepertinya tidak menguntungkan bagi saya. Juga, dengan alasan, bahwa Anda perlu "memisahkan" ORM ini tidak ada artinya.
Jika Anda masih ingin membangun abstraksi ini, saya akan menentang pola Repositori. Itu hebat di zaman SQL murni, tetapi cukup merepotkan dalam menghadapi ORM modern. Terutama karena Anda akhirnya menerapkan kembali sebagian besar fitur ORM, seperti operasi CRUD dan permintaan.
Jika saya membangun abstraksi semacam itu, saya akan menggunakan aturan / pola ini
Dalam implementasi konkret, saya akan menggunakan operasi CRUD ORM secara langsung, tanpa pembungkus apa pun. Saya juga akan melakukan query sederhana langsung dalam kode. Tetapi pertanyaan kompleks akan diringkas dalam objek mereka sendiri. Untuk "menyembunyikan" ORM, saya akan mencoba menyuntikkan konteks data secara transparan ke dalam objek layanan / UI dan telah melakukan hal yang sama pada objek kueri.
Hal terakhir yang ingin saya katakan, adalah bahwa banyak orang menggunakan ORM tanpa mengetahui cara menggunakannya dan bagaimana menghasilkan "keuntungan" terbaik darinya. Orang merekomendasikan repositori biasanya dari jenis ini.
Sebagai bacaan yang direkomendasikan, saya akan mengatakan blog Ayende , terutama artikel ini .
sumber
Masalah dengan implementasi bocor adalah bahwa Anda memerlukan banyak kondisi filter yang berbeda.
Anda dapat mempersempit api ini jika Anda menerapkan metode repositori FindByExample dan menggunakannya seperti ini
sumber
Pertimbangkan untuk membuat ekstensi Anda beroperasi pada IQueryable alih-alih IRepository.
Untuk unit test:
Tidak diperlukan cemoohan pembiayaan untuk pengujian. Anda juga dapat menggabungkan metode ekstensi ini untuk membuat kueri yang lebih kompleks sesuai kebutuhan.
sumber
IQueryable
adalah ibu yang buruk, atau lebih tepatnya antarmuka ALLAH. Menerapkannya sangat dimiliki dan ada sangat sedikit (jika ada) LINQ lengkap untuk penyedia Sql. b) Metode penyuluhan membuat penyuluhan (salah satu prinsip OOP dasar) tidak mungkin.Saya menulis pola objek permintaan yang cukup rapi untuk NHibernate di sini: https://github.com/shaynevanasperen/NHibernate.Sessions.Operations
Ini bekerja dengan menggunakan antarmuka seperti ini:
Diberikan kelas entitas POCO seperti ini:
Anda dapat membuat objek permintaan seperti ini:
Dan kemudian gunakan seperti ini:
sumber