NHibernate vs LINQ ke SQL

117

Sebagai seseorang yang belum pernah menggunakan kedua teknologi tersebut pada proyek dunia nyata, saya bertanya-tanya apakah ada yang tahu bagaimana keduanya saling melengkapi dan seberapa banyak fungsi mereka tumpang tindih?

Manu
sumber

Jawaban:

113

LINQ ke SQL memaksa Anda untuk menggunakan pola tabel per kelas. Manfaat menggunakan pola ini adalah penerapannya yang cepat dan mudah serta hanya membutuhkan sedikit upaya untuk menjalankan domain Anda berdasarkan struktur database yang ada. Untuk aplikasi sederhana, ini sangat dapat diterima (dan seringkali bahkan lebih disukai), tetapi untuk aplikasi yang lebih kompleks, pengembang akan sering menyarankan menggunakan pola desain yang digerakkan oleh domain sebagai gantinya (yang difasilitasi oleh NHibernate).

Masalah dengan pola tabel-per-kelas adalah bahwa struktur database Anda memiliki pengaruh langsung terhadap desain domain Anda. Misalnya, Anda memiliki tabel Pelanggan dengan kolom berikut untuk menyimpan informasi alamat utama pelanggan:

  • Alamat jalan
  • Kota
  • Negara
  • Zip

Sekarang, katakanlah Anda ingin menambahkan kolom untuk alamat surat pelanggan juga sehingga Anda menambahkan kolom berikut ke tabel Pelanggan:

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

Menggunakan LINQ ke SQL, objek Pelanggan di domain Anda sekarang akan memiliki properti untuk masing-masing dari delapan kolom ini. Namun jika Anda mengikuti pola desain berdasarkan domain, Anda mungkin akan membuat kelas Alamat dan kelas Pelanggan Anda memiliki dua properti Alamat, satu untuk alamat surat dan satu untuk alamat mereka saat ini.

Itu adalah contoh sederhana, tetapi ini menunjukkan bagaimana pola tabel per kelas dapat menyebabkan domain yang agak bau. Pada akhirnya, terserah Anda. Sekali lagi, untuk aplikasi sederhana yang hanya membutuhkan fungsionalitas CRUD (buat, baca, perbarui, hapus) dasar, LINQ ke SQL sangat ideal karena kesederhanaannya. Tapi secara pribadi saya suka menggunakan NHibernate karena memfasilitasi domain yang lebih bersih.

Sunting: @lomaxx - Ya, contoh yang saya gunakan sederhana dan bisa dioptimalkan untuk bekerja dengan baik dengan LINQ ke SQL. Saya ingin membuatnya sesederhana mungkin untuk menyampaikan intinya. Intinya tetap bahwa ada beberapa skenario di mana memiliki struktur database Anda menentukan struktur domain Anda akan menjadi ide yang buruk, atau setidaknya mengarah ke desain OO yang kurang optimal.

Kevin Pang
sumber
4
Anda dapat mengkodekan implementasi repositori Anda menggunakan Linq To SQL, ini sangat berguna.
Nicolas Dorier
1
Saya pikir ini bukan ActiveRecord, bahkan kelas yang dipetakan merangkum beberapa logika infrastruktur. Pola ActiveRecord adalah jika Anda bisa memiliki Customer.Save (). L2S mengimplementasikan pola Satuan Kerja dengan kelas DataContext, seperti Sesi di nHibernate, tetapi NH memiliki pendekatan POCO yang nyata.
Hrvoje Hudo
1
@ kevin "LINQ ke SQL menggunakan pola rekaman aktif" Itu tidak benar. Ini seperti mengatakan bahwa ADO.NET menggunakan catatan aktif, atau NHibernate menggunakan catatan aktif. Semuanya adalah teknologi akses data dan tidak memberlakukan pola akses data tertentu. Saya pribadi suka menggunakan linq-to-sql dengan pola repositori. Anda benar bahwa linq-to-sql tidak mendukung pemetaan kompleks seperti yang dilakukan NHibernate.
liammclennan
1
Bagaimana dengan menormalkan database Anda, dan membiarkan DAL Anda dibuat oleh alat yaitu SQLMetal?
Alex
3
@CoffeeAddict Ketika ketidakcocokan impedansi terlalu berat untuk ditanggung, saat itulah aplikasi Anda terlalu rumit untuk menggunakan LINQ ke SQL, imo. Alasan contoh saya bau adalah karena menggunakan LINQ ke SQL akan menghasilkan 8 properti sebagai lawan 2 dan membatasi kemampuan Anda untuk melakukan hal-hal seperti mengimplementasikan fungsi yang mengambil kelas Alamat atau mengimplementasikan rutinitas pada kelas Alamat yang dapat Anda lakukan. lakukan jika Anda pernah menggunakan NHibernate.
Kevin Pang
26

Dua poin yang terlewatkan sejauh ini:

  • LINQ ke SQL tidak berfungsi dengan Oracle atau database apa pun selain SqlServer. Namun pihak ke-3 tawarkan dukungan yang lebih baik untuk Oracle, misalnya DevArt ini dotConnect , DbLinq , Mindscape ini LightSpeed dan ALinq . (Saya tidak memiliki pengalaman pribadi dengan ini)

  • Linq ke NHibernate memungkinkan Anda menggunakan Linq dengan Nhiberate, jadi ini dapat menghilangkan alasan untuk tidak menggunakan.

Juga antarmuka fasih baru ke Nhibernate tampaknya membuatnya lebih mudah untuk mengonfigurasi pemetaan Nhibernate. (Menghapus salah satu titik nyeri Nhibernate)


Memperbarui

Linq ke Nhiberate lebih baik di Nhiberate v3 yang sekarang dalam alpha . Sepertinya Nhiberate v3 mungkin dikirimkan menjelang akhir tahun ini.

The Bingkai Badan Kerja pada .net 4 juga mulai tampak seperti pilihan yang nyata.

Ian Ringrose
sumber
2
Linq ke NHibernate masih dalam tahap yang sangat awal. Ini bukan implementasi yang lengkap, dan bisa dibilang, sama sekali tidak siap untuk digunakan produksi.
liammclennan
Rilis LinqConnect 2.0 yang baru memperkenalkan beberapa fitur tambahan untuk kenyamanan, seperti dukungan pewarisan Tabel Per Jenis, dukungan PLINQ, dan fungsionalitas Pembaruan Batch. ORM Designer (Pengembang Entitas Devart) sekarang memiliki dukungan Model First dan fitur Sinkronisasi Pemetaan. Detail selengkapnya: devart.com/news/2010/dotconnects600.html
Devart
23

@Kevin: Saya pikir masalah dengan contoh yang Anda sajikan adalah Anda menggunakan desain database yang buruk. Saya akan berpikir Anda akan membuat tabel pelanggan dan tabel alamat dan menormalkan tabel. Jika Anda melakukannya, Anda pasti dapat menggunakan Linq To SQL untuk skenario yang Anda sarankan. Scott Guthrie memiliki serangkaian posting yang bagus tentang penggunaan Linq To SQL yang sangat saya sarankan untuk Anda periksa.

Saya tidak berpikir Anda dapat mengatakan LINQ dan NHibernate saling melengkapi karena itu akan menyiratkan bahwa keduanya dapat digunakan bersama, dan sementara ini mungkin, Anda jauh lebih baik memilih satu dan berpegang teguh padanya.

NHibernate memungkinkan Anda untuk memetakan tabel database Anda ke objek domain Anda dengan cara yang sangat fleksibel. Ini juga memungkinkan Anda untuk menggunakan HBL untuk menanyakan database.

Linq ke SQL juga memungkinkan Anda untuk memetakan objek domain Anda ke database, namun menggunakan sintaks kueri Linq untuk melakukan kueri database

Perbedaan utama di sini adalah sintaks kueri Linq diperiksa pada waktu kompilasi oleh kompilator untuk memastikan kueri Anda valid.

Beberapa hal yang harus diperhatikan dengan linq adalah bahwa ini hanya tersedia di .net 3.x dan hanya didukung di VS2008. NHibernate tersedia dalam versi 2.0 dan 3.x serta VS2005.

Beberapa hal yang harus diperhatikan dengan NHibernate adalah bahwa itu tidak menghasilkan objek domain Anda, juga tidak menghasilkan file pemetaan. Anda perlu melakukan ini secara manual. Linq dapat
melakukan ini secara otomatis untuk Anda.

lomaxx
sumber
15
Bagaimana jika Anda menulis kode pada struktur database lama yang tidak dapat Anda ubah karena mendukung aplikasi lain. Apakah Anda ingin model domain Anda mewarisi desain database yang buruk atau Anda ingin membuat model domain kaya yang dapat bervariasi secara independen dari struktur database?
Larry Foulkrod
7

Fluent NHibernate dapat membuat file pemetaan Anda berdasarkan konvensi sederhana. Tidak ada tulisan XML dan diketik dengan kuat.

Saya baru-baru ini mengerjakan sebuah proyek, di mana kami perlu mengubah dari Linq Ke SQL ke NHibernate untuk alasan kinerja. Terutama cara L2S dalam mewujudkan objek tampaknya lebih lambat daripada cara NHibernate dan manajemen perubahannya juga cukup lambat. Dan mungkin sulit untuk menonaktifkan manajemen perubahan untuk skenario tertentu yang tidak diperlukan.

Jika Anda akan menggunakan entitas Anda yang terputus dari DataContext - dalam skenario WCF misalnya - Anda mungkin mengalami banyak masalah saat menghubungkannya ke DataContext lagi untuk memperbarui perubahan. Saya tidak punya masalah dengan NHibernate.

Hal yang akan saya lewatkan dari L2S sebagian besar adalah pembuatan kode yang membuat hubungan tetap mutakhir di kedua ujung entitas. Tapi saya rasa ada beberapa alat bagi NHibernate untuk melakukannya di luar sana juga ...

asgerhallas
sumber
2
Untuk berjaga-jaga jika orang lain membaca posting Anda dan berpikir untuk melompat kapal juga - .ObjectTrackingEnabled = falsepada Anda DataContextakan menyelesaikan masalah pelacakan perubahan Anda. Selama Anda membeli pola unit-of-work dan tidak ingin melakukan DDD, Linq-to-SQL benar-benar memberikannya.
mattmc3
" kami perlu mengubah dari Linq Ke SQL ke NHibernate untuk alasan kinerja " - Setelah menggunakan [Fasih, tidak kurang] NHibernate selama beberapa tahun, saya rasa untuk Anda. Saya pikir kami kebanyakan menipu dan akhirnya menulis SQL asli untuk titik tekanan kinerja nyata. Akan menarik untuk mendengar pembaruan (enam tahun kemudian ...) tentang bagaimana migrasi Anda pergi, dan apakah itu sepadan.
ruffin
5

Bisakah Anda menjelaskan apa yang Anda maksud dengan "LINQ"?

LINQ bukanlah teknologi akses data, ini hanya fitur bahasa yang mendukung kueri sebagai konstruksi asli. Itu dapat menanyakan model objek apa pun yang mendukung antarmuka tertentu (misalnya IQuerable).

Banyak orang menyebut LINQ To SQL sebagai LINQ, tapi itu sama sekali tidak benar. Microsoft baru saja merilis LINQ To Entities dengan .NET 3.5 SP1. Selain itu, NHibernate memiliki antarmuka LINQ, sehingga Anda dapat menggunakan LINQ dan NHibernate untuk mendapatkan data Anda.

Jon Galloway
sumber
2

Dengan LINQ, saya berasumsi yang Anda maksud adalah LINQ ke SQL karena LINQ, dengan sendirinya, tidak memiliki database "berjalan terus" yang terkait dengannya. Itu hanya bahasa kueri yang memiliki muatan gula sintak untuk membuatnya terlihat SQL-ish.

Dalam contoh dasar yang paling dasar, NHibernate dan LINQ to SQL tampaknya keduanya memecahkan masalah yang sama. Setelah Anda lulus, Anda segera menyadari bahwa NHibernate memiliki dukungan untuk banyak fitur yang memungkinkan Anda membuat model domain yang benar-benar kaya. Ada juga proyek LINQ ke NHibernate yang memungkinkan Anda menggunakan LINQ untuk menanyakan NHibernate dengan cara yang sama seperti Anda menggunakan LINQ ke SQL.

Ryan Rinaldi
sumber
1

Pertama mari kita pisahkan dua hal yang berbeda: Pemodelan database berkaitan dengan data sementara pemodelan objek berkaitan dengan entitas dan hubungan.

Keuntungan Linq-to-SQL adalah dengan cepat menghasilkan kelas dari skema database sehingga mereka dapat digunakan sebagai objek rekaman aktif (lihat definisi pola desain rekaman aktif).

Keuntungan NHibernate adalah memungkinkan fleksibilitas antara pemodelan objek dan pemodelan basis data Anda. Database dapat dimodelkan untuk mencerminkan data Anda dengan mempertimbangkan kinerja misalnya. Sementara pemodelan objek Anda akan paling mencerminkan elemen aturan bisnis menggunakan pendekatan seperti Domain-Driven-Design. (lihat komentar Kevin Pang)

Dengan basis data lama dengan pemodelan dan / atau konvensi penamaan yang buruk, maka Linq-to-SQL akan mencerminkan struktur dan nama yang tidak diinginkan ini ke kelas Anda. Namun NHibernate dapat menyembunyikan kekacauan ini dengan pembuat peta data.

Dalam proyek greenfield di mana database memiliki penamaan yang baik dan kompleksitas yang rendah, Linq-to-SQL dapat menjadi pilihan yang baik.

Namun Anda dapat menggunakan Fluent NHibernate dengan pemetaan otomatis untuk tujuan yang sama dengan pemetaan sebagai konvensi. Dalam hal ini Anda tidak perlu khawatir tentang pemeta data dengan XML atau C # dan biarkan NHibernate membuat skema database dari entitas Anda berdasarkan konvensi yang dapat Anda sesuaikan.

Sebaliknya kurva belajar Linq-to-SQL lebih kecil dari NHibernate.

Humberto
sumber
0

Atau Anda dapat menggunakan proyek Castle ActiveRecords. Saya telah menggunakannya untuk waktu yang singkat untuk meningkatkan beberapa kode baru untuk proyek lama. Ini menggunakan NHibernate dan bekerja pada pola rekaman aktif (mengejutkan mengingat namanya, saya tahu). Saya belum mencobanya, tetapi saya berasumsi bahwa setelah Anda menggunakannya, jika Anda merasa perlu untuk langsung turun ke dukungan NHibernate, tidak akan terlalu banyak melakukannya untuk sebagian atau seluruh proyek Anda.


sumber
0

Seperti yang Anda tulis "untuk orang yang belum pernah menggunakan salah satu dari mereka" LINQ ke SQL mudah digunakan sehingga siapa pun dapat menggunakannya dengan mudah. ​​Ini juga mendukung prosedur, yang membantu sebagian besar waktu. Misalkan Anda ingin mendapatkan data dari lebih dari satu tabel kemudian menulis prosedur dan menyeret prosedur itu ke desainer dan itu akan membuat segalanya untuk Anda, Misalkan nama prosedur Anda adalah "CUSTOMER_ORDER_LINEITEM" yang mengambil rekaman dari ketiga tabel ini lalu tulis saja

MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

Anda dapat menggunakan Anda merekam objek di foreach loop juga, yang tidak didukung oleh NHibernate

Ali Adravi
sumber