NHibernate so với LINQ to SQL


117

Là một người chưa sử dụng cả hai công nghệ này trong các dự án trong thế giới thực, tôi tự hỏi liệu có ai biết hai thứ này bổ sung cho nhau như thế nào và chức năng của chúng trùng lặp đến mức nào?

Câu trả lời:


113

LINQ to SQL buộc bạn phải sử dụng mẫu bảng mỗi lớp. Lợi ích của việc sử dụng mẫu này là nó nhanh chóng và dễ dàng thực hiện và chỉ mất rất ít nỗ lực để miền của bạn chạy dựa trên cấu trúc cơ sở dữ liệu hiện có. Đối với các ứng dụng đơn giản, điều này hoàn toàn có thể chấp nhận được (và đôi khi còn thích hợp hơn), nhưng đối với các ứng dụng phức tạp hơn, các nhà phát triển sẽ thường đề xuất sử dụng thiết kế hướng miền mẫu thay thế (đó là điều mà NHibernate tạo điều kiện).

Vấn đề với mô hình bảng mỗi lớp là cấu trúc cơ sở dữ liệu của bạn có ảnh hưởng trực tiếp đến thiết kế miền của bạn. Ví dụ: giả sử bạn có bảng Khách hàng với các cột sau để chứa thông tin địa chỉ chính của khách hàng:

  • StreetAddress
  • Tp.
  • Tiểu bang
  • Zip

Bây giờ, giả sử bạn cũng muốn thêm các cột cho địa chỉ gửi thư của khách hàng, vì vậy bạn thêm các cột sau vào bảng Khách hàng:

  • MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

Sử dụng LINQ to SQL, đối tượng Khách hàng trong miền của bạn bây giờ sẽ có các thuộc tính cho mỗi cột trong số tám cột này. Nhưng nếu bạn đang theo một mẫu thiết kế theo hướng miền, bạn có thể đã tạo một lớp Địa chỉ và để lớp Khách hàng của bạn giữ hai thuộc tính Địa chỉ, một cho địa chỉ gửi thư và một cho địa chỉ hiện tại của chúng.

Đó là một ví dụ đơn giản, nhưng nó chứng minh cách mô hình bảng mỗi lớp có thể dẫn đến một miền hơi có mùi. Cuối cùng, đó là vào bạn. Một lần nữa, đối với các ứng dụng đơn giản chỉ cần chức năng CRUD (tạo, đọc, cập nhật, xóa) cơ bản, LINQ to SQL là lý tưởng vì tính đơn giản. Nhưng cá nhân tôi thích sử dụng NHibernate vì nó tạo điều kiện cho một miền sạch hơn.

Chỉnh sửa: @lomaxx - Có, ví dụ tôi sử dụng rất đơn giản và có thể đã được tối ưu hóa để hoạt động tốt với LINQ to SQL. Tôi muốn giữ nó càng cơ bản càng tốt để lái xe về nhà. Tuy nhiên, vấn đề vẫn còn tồn tại là có một số tình huống trong đó cấu trúc cơ sở dữ liệu xác định cấu trúc miền của bạn sẽ là một ý tưởng tồi, hoặc ít nhất là dẫn đến thiết kế OO không tối ưu.


4
Bạn có thể viết mã việc triển khai kho lưu trữ của mình bằng Linq To SQL, nó rất tiện dụng.
Nicolas Dorier

1
Tôi nghĩ đó không phải là ActiveRecord, ngay cả các lớp được ánh xạ cũng đóng gói một số logic cơ sở hạ tầng. Mẫu ActiveRecord sẽ là nếu bạn có thể có Customer.Save (). L2S triển khai mẫu Unit of Work với lớp DataContext, giống như Session trong nHibernate, nhưng NH có cách tiếp cận POCO thực.
Hrvoje Hudo

1
@kevin "LINQ to SQL sử dụng mẫu bản ghi hoạt động" Điều đó không đúng. Nó giống như nói rằng ADO.NET sử dụng bản ghi hoạt động, hoặc NHibernate sử dụng bản ghi hoạt động. Chúng đều là công nghệ truy cập dữ liệu và không thực thi bất kỳ kiểu truy cập dữ liệu cụ thể nào. Cá nhân tôi thích sử dụng linq-to-sql với mô hình kho lưu trữ. Bạn đúng rằng linq-to-sql không hỗ trợ các ánh xạ phức tạp như NHibernate.
liammclennan

1
Thay vào đó, việc chuẩn hóa cơ sở dữ liệu của bạn và cho phép DAL của bạn được tạo bởi các công cụ tức là SQLMetal thì sao?
Alex,

3
@CoffeeAddict Khi trở kháng không khớp quá mức không thể chịu đựng được, đó là khi ứng dụng của bạn quá phức tạp để sử dụng LINQ to SQL trên imo. Lý do ví dụ của tôi có mùi là bởi vì việc sử dụng LINQ to SQL sẽ dẫn đến 8 thuộc tính trái ngược với 2 và hạn chế khả năng của bạn để thực hiện những việc như triển khai các hàm có trong lớp Địa chỉ hoặc thực hiện các quy trình trên lớp Địa chỉ mà bạn có thể làm gì nếu bạn đã sử dụng NHibernate.
Kevin Pang

26

Hai điểm đã bị bỏ lỡ cho đến nay:

  • LINQ to SQL không hoạt động với Oracle hoặc bất kỳ cơ sở dữ liệu nào ngoài SqlServer. Tuy nhiên, các bên thứ 3 cung cấp hỗ trợ tốt hơn cho Oracle, chẳng hạn như dotConnect của devArt , DbLinq , LightSpeed ​​của MindscapeALinq . (Tôi không có bất kỳ kinh nghiệm cá nhân nào với những thứ này)

  • Linq to NHibernate cho phép bạn sử dụng Linq với Nhiberate, vì vậy nó có thể loại bỏ lý do không sử dụng.

Ngoài ra, giao diện lưu loát mới cho Nhibernate dường như làm cho việc cấu hình ánh xạ của Nhibernate bớt khó khăn hơn. (Loại bỏ một trong những điểm khó khăn của Nhibernate)


Cập nhật

Linq to Nhiberate tốt hơn trong Nhiberate v3 hiện đang ở giai đoạn alpha . Có vẻ như Nhiberate v3 có thể xuất xưởng vào cuối năm nay.

Các Entity Khung làm việc như của .net 4 cũng đang bắt đầu trông giống như một lựa chọn thực sự.


2
Linq đến NHibernate vẫn đang trong giai đoạn rất sớm. Nó không phải là một bản triển khai hoàn chỉnh và có thể nói là chưa sẵn sàng để sử dụng trong sản xuất.
liammclennan 23-07-09

Bản phát hành LinqConnect 2.0 mới giới thiệu một số tính năng bổ sung để thuận tiện, như hỗ trợ kế thừa Table Per Type, hỗ trợ PLINQ và chức năng Cập nhật hàng loạt. ORM Designer (Devart Entity Developer) hiện có hỗ trợ Model First và tính năng Đồng bộ hóa ánh xạ. Thêm chi tiết: devart.com/news/2010/dotconnects600.html
Devart

23

@Kevin: Tôi nghĩ rằng vấn đề với ví dụ bạn đang trình bày là bạn đang sử dụng một thiết kế cơ sở dữ liệu kém. Tôi đã nghĩ rằng bạn sẽ tạo một bảng khách hàng và một bảng địa chỉ và chuẩn hóa các bảng. Nếu bạn làm điều đó, chắc chắn bạn có thể sử dụng Linq To SQL cho trường hợp bạn đang đề xuất. Scott Guthrie có một loạt bài viết về cách sử dụng Linq To SQL mà tôi thực sự khuyên bạn nên xem qua.

Tôi không nghĩ rằng bạn có thể nói Linq và NHibernate bổ sung cho nhau vì điều đó có nghĩa là chúng có thể được sử dụng cùng nhau, và trong khi điều này là có thể, bạn nên chọn một cái và gắn bó với nó.

NHibernate cho phép bạn ánh xạ các bảng cơ sở dữ liệu của mình với các đối tượng miền của bạn theo cách rất linh hoạt. Nó cũng cho phép bạn sử dụng HBL để truy vấn cơ sở dữ liệu.

Linq to SQL cũng cho phép bạn ánh xạ các đối tượng miền của mình với cơ sở dữ liệu tuy nhiên nó sử dụng cú pháp truy vấn Linq để truy vấn cơ sở dữ liệu

Sự khác biệt chính ở đây là cú pháp truy vấn Linq được trình biên dịch kiểm tra tại thời điểm biên dịch để đảm bảo các truy vấn của bạn hợp lệ.

Một số điều cần lưu ý với linq là nó chỉ có sẵn trong .net 3.x và chỉ được hỗ trợ trong VS2008. NHibernate có sẵn trong 2.0 và 3.x cũng như VS2005.

Một số điều cần lưu ý với NHibernate là nó không tạo các đối tượng miền của bạn, cũng như không tạo các tệp ánh xạ. Bạn cần phải làm điều này theo cách thủ công. Linq có thể
làm điều này tự động cho bạn.


15
Điều gì sẽ xảy ra nếu bạn đang viết mã dựa trên cấu trúc cơ sở dữ liệu kế thừa mà bạn không thể thay đổi vì nó hỗ trợ các ứng dụng khác. Bạn muốn mô hình miền của mình kế thừa thiết kế cơ sở dữ liệu nghèo nàn hay bạn muốn tạo mô hình miền phong phú có thể thay đổi độc lập với cấu trúc cơ sở dữ liệu?
Larry Foulkrod

7

NHibernate thông thạo có thể tạo các tệp ánh xạ của bạn dựa trên các quy ước đơn giản. Không có văn bản XML và được đánh máy mạnh.

Gần đây tôi đã làm việc trong một dự án, nơi chúng tôi cần thay đổi từ Linq To SQL sang NHibernate vì lý do hiệu suất. Đặc biệt là cách hiện thực hóa các đối tượng của L2S có vẻ chậm hơn so với ditto của NHibernate và việc quản lý thay đổi cũng khá chậm. Và có thể khó tắt quản lý thay đổi đối với các tình huống cụ thể mà nó không cần thiết.

Nếu bạn định sử dụng các thực thể của mình bị ngắt kết nối khỏi DataContext - ví dụ như trong trường hợp WCF - bạn có thể gặp rất nhiều khó khăn khi kết nối lại chúng với DataContext để cập nhật các thay đổi. Tôi không gặp vấn đề gì với điều đó với NHibernate.

Điều tôi sẽ bỏ lỡ từ L2S chủ yếu là việc tạo mã giữ cho các mối quan hệ được cập nhật ở cả hai đầu của các thực thể. Nhưng tôi đoán cũng có một số công cụ để NHibernate làm điều đó ...


2
Đề phòng trường hợp những người khác đọc bài đăng của bạn và cũng đang nghĩ đến việc nhảy tàu - thì .ObjectTrackingEnabled = falseviệc của bạn DataContextsẽ giải quyết được vấn đề theo dõi thay đổi của bạn. Miễn là bạn mua mô hình đơn vị công việc và không muốn thực hiện DDD, Linq-to-SQL thực sự mang lại hiệu quả.
mattmc3 14/12/10

" chúng tôi cần phải thay đổi từ Linq To SQL sang NHibernate vì lý do hiệu suất " - Đã sử dụng [Fluent, no less] NHibernate trong một vài năm, tôi cảm thấy dành cho bạn. Tôi nghĩ rằng chúng ta hầu hết đã gian lận và kết thúc bằng cách viết SQL gốc cho các điểm áp lực hiệu suất thực tế. Sẽ rất thú vị khi nghe cập nhật (sáu năm sau ...) về quá trình di chuyển của bạn diễn ra như thế nào và liệu nó có xứng đáng hay không.
ruffin

5

Bạn có thể làm rõ những gì bạn có nghĩa là "LINQ"?

LINQ không phải là một công nghệ truy cập dữ liệu, nó chỉ là một tính năng ngôn ngữ hỗ trợ truy vấn như một cấu trúc gốc. Nó có thể truy vấn bất kỳ mô hình đối tượng nào hỗ trợ các giao diện cụ thể (ví dụ: IQueryable).

Nhiều người gọi LINQ To SQL là LINQ, nhưng điều đó hoàn toàn không chính xác. Microsoft vừa phát hành LINQ To Entities với .NET 3.5 SP1. Ngoài ra, NHibernate có giao diện LINQ, vì vậy bạn có thể sử dụng LINQ và NHibernate để lấy dữ liệu của mình.


2

Với LINQ, tôi cho rằng bạn muốn nói đến LINQ với SQL vì bản thân LINQ không có cơ sở dữ liệu nào liên quan đến nó. Nó chỉ là một ngôn ngữ truy vấn có một lượng lớn cú pháp để làm cho nó trông giống như SQL-ish.

Trong phần rất cơ bản của các ví dụ cơ bản, NHibernate và LINQ to SQL dường như đều giải quyết cùng một vấn đề. Khi bạn nhận được thông báo, bạn sẽ sớm nhận ra rằng NHibernate hỗ trợ rất nhiều tính năng cho phép bạn tạo các mô hình miền thực sự phong phú. Ngoài ra còn có một dự án LINQ to NHibernate cho phép bạn sử dụng LINQ để truy vấn NHibernate theo cách giống như cách bạn sử dụng LINQ to SQL.


1

Đầu tiên chúng ta hãy phân tách hai điều khác nhau: Mô hình cơ sở dữ liệu quan tâm đến dữ liệu trong khi mô hình hóa đối tượng quan tâm đến các thực thể và mối quan hệ.

Ưu điểm của Linq-to-SQL là nhanh chóng tạo ra các lớp từ lược đồ cơ sở dữ liệu để chúng có thể được sử dụng như các đối tượng bản ghi hoạt động (xem định nghĩa mẫu thiết kế bản ghi tích cực).

Lợi thế của NHibernate là cho phép sự linh hoạt giữa mô hình hóa đối tượng và mô hình cơ sở dữ liệu của bạn. Cơ sở dữ liệu có thể được mô hình hóa để phản ánh tốt nhất dữ liệu của bạn khi xem xét hiệu suất. Mặc dù mô hình đối tượng của bạn sẽ phản ánh tốt nhất các yếu tố của quy tắc kinh doanh bằng cách sử dụng cách tiếp cận như Thiết kế theo hướng miền. (xem bình luận của Kevin Pang)

Với cơ sở dữ liệu cũ có mô hình hóa kém và / hoặc quy ước đặt tên thì Linq-to-SQL sẽ phản ánh cấu trúc và tên không mong muốn này cho các lớp của bạn. Tuy nhiên NHibernate có thể che giấu mớ hỗn độn này bằng các trình lập bản đồ dữ liệu.

Trong các dự án greenfield nơi cơ sở dữ liệu có cách đặt tên tốt và độ phức tạp thấp, Linq-to-SQL có thể là lựa chọn tốt.

Tuy nhiên, bạn có thể sử dụng Fluent NHibernate với ánh xạ tự động cho cùng mục đích này với ánh xạ theo quy ước. Trong trường hợp này, bạn đừng lo lắng về bất kỳ trình ánh xạ dữ liệu nào với XML hoặc C # và hãy để NHibernate tạo lược đồ cơ sở dữ liệu từ các thực thể của bạn dựa trên quy ước mà bạn có thể tùy chỉnh.

Mặt khác, đường cong học tập của Linq-to-SQL nhỏ hơn NHibernate.


0

Hoặc bạn có thể sử dụng dự án Castle ActiveRecords. Tôi đã sử dụng nó trong một thời gian ngắn để tăng cường một số mã mới cho một dự án kế thừa. Nó sử dụng NHibernate và hoạt động trên mẫu bản ghi đang hoạt động (đáng ngạc nhiên với cái tên mà tôi biết). Tôi chưa thử, nhưng tôi cho rằng khi bạn đã sử dụng nó, nếu bạn cảm thấy cần phải trực tiếp chuyển đến hỗ trợ NHibernate, thì sẽ không quá nhiều nếu bạn làm như vậy cho một phần hoặc toàn bộ dự án của mình.


0

Như bạn đã viết "cho một người chưa sử dụng một trong hai" LINQ to SQL rất dễ sử dụng nên bất kỳ ai cũng có thể sử dụng nó một cách dễ dàng Nó cũng hỗ trợ các thủ tục, điều này giúp ích trong hầu hết thời gian. Giả sử bạn muốn lấy dữ liệu từ nhiều bảng, sau đó viết một thủ tục và kéo thủ tục đó vào trình thiết kế và nó sẽ tạo mọi thứ cho bạn, Giả sử tên thủ tục của bạn là "CUSTOMER_ORDER_LINEITEM" tìm nạp bản ghi từ tất cả ba bảng này, sau đó chỉ cần ghi

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

bạn cũng có thể sử dụng đối tượng record của bạn trong vòng lặp foreach, đối tượng này không được NHibernate hỗ trợ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.