Rumah pembangunan bahagian belakang C++ Akses data dalam kod, menggunakan repositori, walaupun dengan ORM

Akses data dalam kod, menggunakan repositori, walaupun dengan ORM

Dec 25, 2024 am 11:21 AM

Data access in code, using repositories, even with ORMs

Pengenalan

Dalam dunia .NET, salah satu kaedah yang paling banyak digunakan untuk mengakses pangkalan data ialah dengan Rangka Kerja Entiti (EF), Object Relational Mapper (ORM) yang disepadukan rapat dengan sintaks bahasa. Menggunakan Pertanyaan Bersepadu Bahasa (LINQ) asli kepada bahasa .NET, ia menjadikan akses data terasa seperti bekerja dengan koleksi .NET biasa, tanpa banyak pengetahuan tentang SQL. Ini mempunyai kebaikan dan keburukan yang saya akan cuba untuk tidak bercakap tentang di sini. Tetapi salah satu isu yang ia wujudkan secara konsisten ialah kekeliruan mengenai struktur projek perisian, tahap abstraksi dan akhirnya ujian unit.

Siaran ini akan cuba menerangkan sebab abstraksi repositori SENTIASA berguna. Ambil perhatian bahawa ramai orang menggunakan repositori sebagai istilah untuk capaian data abstrak, sementara terdapat juga corak perisian repositori yang berkaitan dengan perkara yang serupa, tetapi ia bukan perkara yang sama. Di sini, saya akan memanggil repositori satu siri antara muka yang mengabstrakkan butiran pelaksanaan akses data dan mengabaikan corak reka bentuk sepenuhnya.

Sejarah

Jangan teragak-agak untuk melangkau ini jika anda menyedarinya, tetapi saya perlu terlebih dahulu menangani bagaimana kita mendapat idea repositori untuk bermula.

Dalam prasejarah, kod hanya ditulis seperti sedia ada, tanpa struktur, segala-galanya, melakukan apa yang anda mahu ia lakukan atau sekurang-kurangnya berharap. Tiada ujian automatik, hanya penggodaman dan ujian manual sehingga ia berjaya. Setiap aplikasi ditulis dalam apa sahaja yang ada, dengan kebimbangan tentang keperluan perkakasan yang lebih penting daripada struktur kod, penggunaan semula atau kebolehbacaan. Itulah yang membunuh dinosaur! Fakta yang benar.

Perlahan-lahan, corak mula muncul. Untuk aplikasi perniagaan khususnya, terdapat pemisahan yang jelas bagi kod perniagaan, ketekunan data dan antara muka pengguna. Ini dipanggil lapisan dan tidak lama lagi dipisahkan kepada projek yang berbeza, bukan sahaja kerana ia merangkumi kebimbangan yang berbeza, tetapi juga kerana kemahiran yang diperlukan untuk membinanya adalah berbeza. Reka bentuk UI sangat berbeza daripada kerja logik kod dan sangat berbeza daripada SQL atau apa sahaja bahasa atau sistem yang digunakan untuk mengekalkan data.

Oleh itu, interaksi antara perniagaan dan lapisan data dilakukan dengan mengabstrakkannya ke dalam antara muka dan model. Sebagai kelas perniagaan, anda tidak akan meminta senarai entri dalam jadual, anda memerlukan senarai objek kompleks yang ditapis. Adalah menjadi tanggungjawab lapisan data untuk mengakses apa sahaja yang berterusan dan memetakannya kepada sesuatu yang boleh difahami oleh perniagaan. Abstraksi ini mula dipanggil repositori.

Pada lapisan bawah akses data, corak seperti CRUD cepat mengambil alih: anda menentukan bekas kegigihan berstruktur seperti jadual dan anda akan membuat, membaca, mengemas kini atau memadam rekod. Dalam kod, logik jenis ini akan diabstraksikan kepada koleksi, seperti Senarai, Kamus atau Tatasusunan. Oleh itu, terdapat juga pendapat semasa bahawa repositori harus berkelakuan seperti koleksi, malah mungkin cukup generik untuk tidak mempunyai kaedah lain selain daripada mencipta, membaca, mengemas kini dan memadam.

Namun, saya sangat tidak bersetuju. Sebagai abstraksi capaian data daripada perniagaan, ia harus dijauhkan sejauh mungkin daripada corak untuk akses data, sebaliknya dimodelkan berdasarkan keperluan perniagaan. Di sinilah pemikiran Rangka Kerja Entiti khususnya, tetapi banyak ORM lain, mula bercanggah dengan idea asal repositori, yang memuncak dengan panggilan untuk tidak menggunakan repositori dengan EF, memanggilnya sebagai antipattern.

Lebih banyak lapisan

Banyak kekeliruan dijana oleh hubungan ibu bapa-anak antara model. Seperti entiti Jabatan dengan Orang di dalamnya. Sekiranya repositori jabatan mengembalikan model yang mengandungi orang? Mungkin tidak. Jadi bagaimana pula dengan kita memisahkan repositori kepada jabatan (tanpa orang) dan orang, kemudian mempunyai abstraksi berasingan untuk dipetakan kemudian kepada model perniagaan?

Kekeliruan sebenarnya bertambah apabila kita mengambil lapisan perniagaan dan memisahkannya kepada sublapisan. Sebagai contoh, apa yang kebanyakan orang panggil perkhidmatan perniagaan ialah abstraksi terhadap penggunaan logik perniagaan tertentu hanya pada jenis model perniagaan tertentu. Katakan apl anda berfungsi dengan orang, jadi anda mempunyai model yang dipanggil Person. Kelas untuk mengendalikan orang ialah PeopleService, yang akan mendapatkan model perniagaan daripada lapisan kegigihan melalui PeopleRepository, tetapi juga melakukan perkara lain, termasuk pemetaan antara model data dan model perniagaan atau kerja khusus yang hanya berkaitan dengan orang, seperti mengira mereka gaji. Walau bagaimanapun, kebanyakan logik perniagaan menggunakan berbilang jenis model, jadi perkhidmatan akhirnya menjadi pembalut pemetaan ke atas repositori, dengan sedikit tanggungjawab tambahan.

Sekarang bayangkan anda menggunakan EF untuk mengakses data. Anda sudah perlu mengisytiharkan kelas DbContext yang mengandungi koleksi entiti yang anda petakan ke jadual SQL. Anda mempunyai LINQ untuk mengulang, menapis dan memetakannya, yang ditukar dengan cekap kepada arahan SQL di latar belakang dan memberikan anda apa yang anda perlukan, lengkap dengan struktur induk-anak berhierarki. Penukaran itu juga menjaga pemetaan jenis data perniagaan dalaman, seperti enum tertentu atau struktur data pelik. Jadi mengapa anda memerlukan repositori, mungkin juga perkhidmatan?

Saya percaya bahawa walaupun lebih banyak lapisan abstrak mungkin kelihatan seperti overhead yang sia-sia, ia meningkatkan pemahaman manusia tentang projek dan meningkatkan kelajuan dan kualiti perubahan. Terdapat keseimbangan, jelas sekali, saya telah melihat sistem yang direka bentuk dengan keperluan yang jelas bahawa semua corak reka bentuk perisian digunakan di mana-mana. Abstraksi hanya berguna jika ia meningkatkan kebolehbacaan kod dan pengasingan kebimbangan.

Sebab

Salah satu konteks di mana EF menjadi menyusahkan ialah ujian unit. DbContext ialah sistem yang rumit, dengan banyak kebergantungan yang seseorang itu perlu mengejek secara manual dengan usaha yang gigih. Oleh itu Microsoft datang dengan idea: dalam pembekal pangkalan data memori. Jadi untuk menguji apa-apa, anda hanya menggunakan pangkalan data dalam memori dan selesai dengannya.

Perhatikan bahawa pada halaman Microsoft kaedah ujian ini kini ditandai dengan "tidak disyorkan". Juga ambil perhatian bahawa walaupun dalam contoh tersebut, EF diabstraksikan oleh repositori.

Semasa dalam ujian pangkalan data memori berfungsi, mereka menambah beberapa isu yang tidak mudah untuk ditangani:

  • menyediakan DbContext dalam memori memerlukan semua kebergantungan kepada entiti sedia ada
  • menyediakan dan memulakan pangkalan data memori untuk setiap ujian adalah perlahan
  • untuk mendapatkan output pangkalan data yang sah, anda perlu menyediakan lebih banyak daripada yang anda mahu uji secara atom

Oleh itu, apa yang akhirnya berlaku ialah orang menyediakan segala-galanya dalam pangkalan data dalam kaedah "pembantu", kemudian mencipta ujian yang bermula dengan kaedah yang sukar difahami dan kompleks ini untuk menguji kefungsian yang paling kecil sekalipun. Mana-mana kod yang mengandungi kod EF tidak boleh diuji tanpa persediaan ini.

Jadi satu sebab untuk menggunakan repositori adalah untuk mengalihkan abstraksi ujian di atas DbContext. Kini anda tidak memerlukan pangkalan data sama sekali, hanya olok-olok repositori. Kemudian uji repo anda sendiri dalam ujian integrasi menggunakan pangkalan data sebenar. Pangkalan data dalam ingatan sangat hampir dengan pangkalan data sebenar, tetapi ia juga sedikit berbeza.

Sebab lain, yang saya akui jarang saya lihat mempunyai nilai sebenar dalam kehidupan sebenar, ialah anda mungkin mahu mengubah cara anda mengakses data. Mungkin anda ingin menukar kepada NoSql, atau beberapa sistem cache teragih memori. Atau, yang lebih berkemungkinan besar, anda bermula dengan struktur pangkalan data, mungkin pangkalan data monolitik, dan kini anda ingin memfaktorkannya semula ke dalam berbilang pangkalan data dengan struktur jadual yang berbeza. Izinkan saya memberitahu anda dengan segera bahawa ini adalah MUSTAHIL tanpa repositori.

Dan khusus untuk Rangka Kerja Entiti, entiti yang anda dapat ialah rekod aktif, dipetakan ke pangkalan data. Anda membuat perubahan dalam satu dan menyimpan perubahan untuk yang lain dan anda tiba-tiba mendapat entiti pertama dikemas kini dalam db juga. Atau mungkin anda tidak, kerana anda tidak memasukkan sesuatu, atau konteksnya telah berubah.

Penyokong EF sentiasa menggembar-gemburkan penjejakan entiti sebagai perkara yang sangat positif. Katakan anda mendapat entiti daripada pangkalan data, anda kemudian menjalankan perniagaan, kemudian anda mengemas kini entiti dan menyimpannya. Dengan repo anda akan mendapat data, kemudian menjalankan perniagaan, kemudian mendapatkan data sekali lagi untuk melakukan sedikit kemas kini. EF akan menyimpannya dalam ingatan, tahu ia tidak dikemas kini sebelum perubahan anda, jadi ia tidak akan membacanya dua kali. Itu benar. Mereka menerangkan cache memori untuk pangkalan data yang entah bagaimana menyedari perubahan pangkalan data dan menjejaki semua yang anda kendalikan daripada pangkalan data, melainkan jika diarahkan sebaliknya, dua hala memetakan entri pangkalan data ke entiti C# yang kompleks dan menjejaki perubahan berulang-alik, sambil dibenamkan secara mendalam dalam kod perniagaan. Secara peribadi, saya percaya banyak tanggungjawab dan kekurangan pengasingan kebimbangan ini jauh lebih merosakkan daripada prestasi yang diperoleh dengan menggunakannya. Selain itu, dengan beberapa usaha awal, semua fungsi itu masih boleh diabstraksikan dalam repositori, atau mungkin satu lagi lapisan cache memori untuk repositori, sambil mengekalkan sempadan yang jelas antara perniagaan, cache dan akses data.

Malah, kesukaran sebenar dalam semua ini ialah menentukan sempadan antara sistem yang sepatutnya mempunyai kebimbangan yang berasingan. Sebagai contoh, seseorang boleh memperoleh banyak prestasi dengan memindahkan logik penapisan ke prosedur tersimpan dalam pangkalan data, tetapi itu kehilangan kebolehujian dan kebolehbacaan algoritma yang digunakan. Sebaliknya, memindahkan semua logik ke kod, menggunakan EF atau beberapa mekanisme lain, adalah kurang berprestasi dan kadangkala tidak boleh dilaksanakan. Atau di manakah titik di mana entiti data menjadi entiti perniagaan (lihat contoh di atas dengan Jabatan dan Orang)?

Mungkin strategi terbaik adalah dengan mentakrifkan sempadan ini dahulu, kemudian memutuskan teknologi dan reka bentuk mana yang akan sesuai dengannya.

kesimpulan saya

Saya percaya bahawa abstraksi perkhidmatan dan repositori harus sentiasa digunakan, walaupun repositori menggunakan Rangka Kerja Entiti atau ORM lain di bawahnya. Semuanya bermuara kepada pengasingan kebimbangan. Saya tidak akan menganggap Rangka Kerja Entiti sebagai abstraksi perisian yang berguna kerana ia disertakan dengan banyak bagasi, oleh itu repositori banyak digunakan untuk mengabstrakkannya dalam kod. EF ialah abstraksi yang berguna, tetapi untuk akses pangkalan data, bukan dalam perisian.

Falsafah penulisan perisian saya ialah anda bermula dengan keperluan aplikasi, anda mencipta komponen untuk keperluan tersebut dan mengabstrak mana-mana fungsi peringkat rendah dengan antara muka. Anda kemudian mengulangi proses pada peringkat seterusnya, sentiasa memastikan kod itu boleh dibaca dan ia tidak memerlukan pemahaman tentang komponen yang digunakan atau yang digunakan pada tahap semasa. Jika itu tidak berlaku, anda telah memisahkan kebimbangan dengan teruk. Oleh itu, memandangkan tiada aplikasi perniagaan pernah mempunyai keperluan untuk menggunakan pangkalan data atau ORM tertentu, abstraksi lapisan data harus menyembunyikan semua pengetahuan mengenainya.

Apa yang perniagaan mahukan? Senarai orang yang ditapis? var people = service.GetFilteredListOfPeople(filter); tidak kurang, tidak lebih. dan kaedah perkhidmatan hanya akan mengembalikan mapPeople(repo.GetFilteredListOfPeople(mappedFilter)); sekali lagi tidak kurang atau lebih. Bagaimana repo itu mendapatkan orang ramai, menyelamatkan orang ramai atau melakukan apa-apa lagi bukanlah kebimbangan perkhidmatan itu. Anda mahu caching, kemudian laksanakan beberapa mekanisme caching yang melaksanakan IPeopleRepository dan mempunyai pergantungan pada IPeopleRepository. Anda mahu pemetaan, laksanakan antara muka IMapper yang betul. Dan seterusnya.

Saya harap saya tidak terlalu verbose dalam artikel ini. Saya secara khusus menyimpan contoh kod daripadanya, kerana ini lebih kepada isu konseptual, bukan perisian. Rangka Kerja Entiti mungkin menjadi sasaran kebanyakan aduan saya di sini, tetapi ini terpakai pada mana-mana sistem yang ajaib membantu anda dalam perkara kecil, tetapi memecahkan yang penting.

Semoga ia membantu!

Atas ialah kandungan terperinci Akses data dalam kod, menggunakan repositori, walaupun dengan ORM. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Struktur Data Bahasa C: Perwakilan Data dan Operasi Pokok dan Grafik Struktur Data Bahasa C: Perwakilan Data dan Operasi Pokok dan Grafik Apr 04, 2025 am 11:18 AM

Struktur Data Bahasa C: Perwakilan data pokok dan graf adalah struktur data hierarki yang terdiri daripada nod. Setiap nod mengandungi elemen data dan penunjuk kepada nod anaknya. Pokok binari adalah jenis pokok khas. Setiap nod mempunyai paling banyak dua nod kanak -kanak. Data mewakili structtreenode {intData; structtreenode*left; structtreenode*right;}; Operasi mewujudkan pokok traversal pokok (predecision, in-order, dan kemudian pesanan) Node Node Carian Pusat Node Node adalah koleksi struktur data, di mana unsur-unsur adalah simpul, dan mereka boleh dihubungkan bersama melalui tepi dengan data yang betul atau tidak jelas yang mewakili jiran.

Kebenaran di sebalik masalah operasi fail bahasa C Kebenaran di sebalik masalah operasi fail bahasa C Apr 04, 2025 am 11:24 AM

Kebenaran mengenai masalah operasi fail: Pembukaan fail gagal: Kebenaran yang tidak mencukupi, laluan yang salah, dan fail yang diduduki. Penulisan data gagal: Penampan penuh, fail tidak boleh ditulis, dan ruang cakera tidak mencukupi. Soalan Lazim Lain: Traversal fail perlahan, pengekodan fail teks yang salah, dan kesilapan bacaan fail binari.

Apakah keperluan asas untuk fungsi bahasa C Apakah keperluan asas untuk fungsi bahasa C Apr 03, 2025 pm 10:06 PM

Fungsi bahasa C adalah asas untuk modularization kod dan bangunan program. Mereka terdiri daripada pengisytiharan (tajuk fungsi) dan definisi (badan fungsi). Bahasa C menggunakan nilai untuk lulus parameter secara lalai, tetapi pembolehubah luaran juga boleh diubahsuai menggunakan lulus alamat. Fungsi boleh mempunyai atau tidak mempunyai nilai pulangan, dan jenis nilai pulangan mestilah selaras dengan perisytiharan. Penamaan fungsi harus jelas dan mudah difahami, menggunakan nomenclature unta atau garis bawah. Ikuti prinsip tanggungjawab tunggal dan pastikan kesederhanaan fungsi untuk meningkatkan kebolehkerjaan dan kebolehbacaan.

Definisi nama fungsi dalam bahasa c Definisi nama fungsi dalam bahasa c Apr 03, 2025 pm 10:03 PM

Definisi nama fungsi bahasa C termasuk: jenis nilai pulangan, nama fungsi, senarai parameter dan badan fungsi. Nama fungsi harus jelas, ringkas dan bersatu dalam gaya untuk mengelakkan konflik dengan kata kunci. Nama fungsi mempunyai skop dan boleh digunakan selepas pengisytiharan. Penunjuk fungsi membolehkan fungsi diluluskan atau ditugaskan sebagai hujah. Kesalahan umum termasuk konflik penamaan, ketidakcocokan jenis parameter, dan fungsi yang tidak diisytiharkan. Pengoptimuman prestasi memberi tumpuan kepada reka bentuk dan pelaksanaan fungsi, sementara kod yang jelas dan mudah dibaca adalah penting.

Konsep fungsi bahasa c Konsep fungsi bahasa c Apr 03, 2025 pm 10:09 PM

F Fungsi bahasa adalah blok kod yang boleh diguna semula. Mereka menerima input, melakukan operasi, dan hasil pulangan, yang secara modular meningkatkan kebolehgunaan dan mengurangkan kerumitan. Mekanisme dalaman fungsi termasuk parameter lulus, pelaksanaan fungsi, dan nilai pulangan. Seluruh proses melibatkan pengoptimuman seperti fungsi dalam talian. Fungsi yang baik ditulis mengikut prinsip tanggungjawab tunggal, bilangan parameter kecil, penamaan spesifikasi, dan pengendalian ralat. Penunjuk yang digabungkan dengan fungsi dapat mencapai fungsi yang lebih kuat, seperti mengubahsuai nilai pembolehubah luaran. Pointer fungsi meluluskan fungsi sebagai parameter atau alamat kedai, dan digunakan untuk melaksanakan panggilan dinamik ke fungsi. Memahami ciri dan teknik fungsi adalah kunci untuk menulis program C yang cekap, boleh dipelihara, dan mudah difahami.

Cara Mengira C-SubScript 3 Subscript 5 C-SubScript 3 Subscript 5 Algoritma Tutorial Cara Mengira C-SubScript 3 Subscript 5 C-SubScript 3 Subscript 5 Algoritma Tutorial Apr 03, 2025 pm 10:33 PM

Pengiraan C35 pada dasarnya adalah matematik gabungan, yang mewakili bilangan kombinasi yang dipilih dari 3 dari 5 elemen. Formula pengiraan ialah C53 = 5! / (3! * 2!), Yang boleh dikira secara langsung oleh gelung untuk meningkatkan kecekapan dan mengelakkan limpahan. Di samping itu, memahami sifat kombinasi dan menguasai kaedah pengiraan yang cekap adalah penting untuk menyelesaikan banyak masalah dalam bidang statistik kebarangkalian, kriptografi, reka bentuk algoritma, dll.

CS-Week 3 CS-Week 3 Apr 04, 2025 am 06:06 AM

Algorithms are the set of instructions to solve problems, and their execution speed and memory usage vary. In programming, many algorithms are based on data search and sorting. Artikel ini akan memperkenalkan beberapa algoritma pengambilan data dan penyortiran. Carian linear mengandaikan bahawa terdapat array [20,500,10,5,100,1,50] dan perlu mencari nombor 50. Algoritma carian linear memeriksa setiap elemen dalam array satu demi satu sehingga nilai sasaran dijumpai atau array lengkap dilalui. Carta aliran algoritma adalah seperti berikut: kod pseudo untuk carian linear adalah seperti berikut: periksa setiap elemen: jika nilai sasaran dijumpai: pulih semula benar-benar pelaksanaan bahasa palsu c: #termasuk #termasukintmain (tidak sah) {i

C# vs C: Sejarah, evolusi, dan prospek masa depan C# vs C: Sejarah, evolusi, dan prospek masa depan Apr 19, 2025 am 12:07 AM

Sejarah dan evolusi C# dan C adalah unik, dan prospek masa depan juga berbeza. 1.C dicipta oleh BjarnestroustRup pada tahun 1983 untuk memperkenalkan pengaturcaraan berorientasikan objek ke dalam bahasa C. Proses evolusinya termasuk pelbagai standardisasi, seperti C 11 memperkenalkan kata kunci auto dan ekspresi Lambda, C 20 memperkenalkan konsep dan coroutin, dan akan memberi tumpuan kepada pengaturcaraan prestasi dan sistem pada masa akan datang. 2.C# telah dikeluarkan oleh Microsoft pada tahun 2000. Menggabungkan kelebihan C dan Java, evolusinya memberi tumpuan kepada kesederhanaan dan produktiviti. Sebagai contoh, C#2.0 memperkenalkan generik dan C#5.0 memperkenalkan pengaturcaraan tak segerak, yang akan memberi tumpuan kepada produktiviti pemaju dan pengkomputeran awan pada masa akan datang.

See all articles