2013-02-22 39 views
21

Tôi chỉ mới bắt đầu với NHibernate (sử dụng SQLite) trong dự án hiện tại của tôi và tôi chủ yếu sử dụng Query<>, bởi vì tôi đã quen thuộc viết các truy vấn db trong LINQ.Sự khác nhau giữa NHibernate Query <> vs QueryOver <> là gì?

Khi tôi đang phải đối mặt với một số truy vấn phức tạp hơn, tôi đã làm một số nghiên cứu về QueryOver<> và figured rằng nó nên được ưa chuộng hơn vì Query<>"cú pháp QueryOver là NH cụ thể". Ngoài ra, có vẻ như không có gì mà Query<> có thể làm điều đó QueryOver<> không thể thực hiện được.

Vì vậy, tôi đã bắt đầu thay thế tất cả các tập quán của Query<> cho phù hợp. Nó không lâu trước khi tôi có "vấn đề" đầu tiên khi sử dụng Query<> dường như thuận tiện hơn. Ví dụ (chọn giá trị cao nhất từ ​​cột CustomNumber trong bảng BillingDataEntity):

int result = Session.Query<BillingDataEntity>().Select(x => x.CustomNumber).OrderByDescending(a => a).FirstOrDefault(); 
int result = Session.QueryOver<BillingDataEntity>().Select(x => x.CustomNumber).OrderBy(a => a.CustomNumber).Desc.Take(1).SingleOrDefault<int>(); 

Những gì tôi không thích là sự cần thiết để đúc một cách rõ ràng là kết quả để int và rằng các truy vấn <> phiên bản chỉ là dễ dàng hơn để đọc. Tôi nhận được truy vấn hoàn toàn sai, hoặc nói cách khác: Có cách nào tốt hơn để làm điều đó?

tôi đã xem xét kết quả SQL tạo:

NHibernate: select billingdat0_.CustomNumber as col_0_0_ from "BillingDataEntity" billingdat0_ order by billingdat0_.CustomNumber desc limit 1 
NHibernate: SELECT this_.CustomNumber as y0_ FROM "BillingDataEntity" this_ ORDER BY this_.CustomNumber desc limit @p0;@p0 = 1 [Type: Int32 (0)] 

gì chính xác đang i nhìn vào? Đây có phải là truy vấn "nội bộ" (phương pháp phụ thuộc) mà NHibernate tiếp tục dịch sang truy vấn cơ sở dữ liệu thực tế?

Trả lời

26

Có rất nhiều câu trả lời liên quan đến QueryOver so với truy vấn ở đây trên Stackoverflow nhưng trong một nutshell: -

QueryOver là một phiên bản mạnh mẽ-gõ của Tiêu chuẩn, và nhiều NHibernate cụ thể. Khá nhiều thứ bạn có thể làm trong ICriteria có thể được thực hiện với QueryOver. Trong những ngày vàng của ICriteria NH2 bạn luôn có để cast, do đó đây là lý do tại sao bây giờ bạn cần cast ở cuối của chuỗi quay trở lại một int.

LINQ (Query) là một phương pháp truy vấn tiêu chuẩn hoạt động trên IQueryable rằng không cần tài liệu tham khảo rõ ràng để NHibernate và có thể được coi hơn ORM thuyết bất khả tri và do đó theo tiêu chuẩn LINQ. Khi bạn chỉ ra đúng, bạn không cần phải truyền tới một int khi bạn đang chọn kết quả là customNumber.

Tôi sẽ rất ngạc nhiên với ví dụ đơn giản của bạn nếu SQL được tạo là rất khác nhau.

Tôi là người hâm mộ lớn của QueryOver nhưng khi nhà cung cấp LINQ ngày càng trưởng thành hơn thì 95% truy vấn của tôi tôi sử dụng Query nhưng đối với một số nội dung Nhibernate cụ thể, tôi quay trở lại QueryOver. Dù bằng cách nào tôi khuyên bạn nên sử dụng một công cụ định hình để xem những gì bạn có thể sống với.

Refs: Tradeoffs hoặc versusversus

+0

Tôi không chắc chắn bạn có thể trả lời câu hỏi đầu tiên của bạn trực tiếp như câu trả lời của tôi chỉ ra rằng QueryOver được dựa trên ICiteria và 'đây là cách nó đã được thực hiện bạn đang làm nó một cách chính xác'. Để xem SQL được tạo ra, tôi sẽ sử dụng một công cụ thương mại như NHProf vì nó là tốt nhất trên mạng. Không có nghĩa là cùn và HTH làm rõ câu trả lời tôi đã đưa ra. – Rippo

+0

Cảm ơn bạn, hãy +1 cho một số thông tin hữu ích. –

+1

Ngoài ra, 'Truy vấn ' trả về một 'IQueryable' là một 'IEnumerable' để nó siêu thuận tiện. – Jess

3

Về phiên bản QueryOver bạn, tôi sẽ có văn bản:

int result = Session.QueryOver<BillingDataEntity>() 
       .Select(Projections.Max<BillingDataEntity>(x => x.CustomNumber)) 
       .SingleOrDefault<int>(); 

Nó có vẻ khá dễ đọc, và SQL kết quả sẽ là một cái gì đó như:

SELECT max(this_.CustomNumber) as y0_ FROM "BillingDataEntity" this_ 

Hy vọng điều này sẽ giúp

Các vấn đề liên quan