2012-09-04 17 views
12

Truy vấn Aggregate của VB.NET có thiếu sót khi được sử dụng như mệnh đề đầu tiên (bên ngoài) của biểu thức LINQ với nhiều mệnh đề Into vì mỗi mệnh đề Into được thực hiện riêng biệt không?Tổng hợp có bị thiếu sót nghiêm trọng do mỗi mệnh đề vào được thực hiện riêng biệt không?

Câu trả lời "dễ thấy" đối SELECT MIN(ZoneMin), MAX(ZoneMin) FROM Plant in LINQ to SQL

Dim limits = Aggregate p In Plants Select p.ZoneMin Into Min(), Max() 

Tuy nhiên, câu trả lời này thực sự lấy mỗi MinMax (và nếu bạn bao gồm chức năng tổng hợp khác như CountAverage) trong truy vấn SQL riêng . Điều này có thể dễ dàng nhìn thấy trong LINQPad.

Có giao dịch nào (hoặc điều gì khác khiến cho các truy vấn này nguyên tử) không được hiển thị bởi LINQPad hay đây là tình trạng chạy đua đang chờ xảy ra? (Và vì vậy bạn phải thực hiện các thủ thuật được hiển thị trong câu trả lời cho câu hỏi trên để buộc một truy vấn trả về nhiều tập hợp.)

Tóm lại, có truy vấn LINQ to SQL sử dụng Aggregate trả về nhiều tập hợp trong một truy vấn đơn (hoặc ít nhất là "nguyên tử")?

(Tôi cũng nói "rõ ràng" vì câu trả lời rõ ràng với tôi, Aggregate p In Plants Into Min(p.ZoneMin), Max(p.ZoneMin), thực sự lấy toàn bộ bảng hai lần, ngay cả khi được tối ưu hóa, và sau đó sử dụng LINQ-to-Entities MinMax để có được kết quả: -()

tôi nghĩ Aggregate không VB cụ thể, nhưng có vẻ như C# không có biểu thức truy vấn này, vì vậy tôi đã thay đổi để

+0

Bạn có thể xác minh xem các truy vấn có trong giao dịch hay không bằng cách truy tìm máy chủ SQL, nó sẽ hiển thị nó (nhưng tôi không chắc chắn 100% về nó). Tuy nhiên, nếu hiệu suất không phải là mối quan tâm chính, bạn nên đọc toàn bộ tập dữ liệu và tổng hợp sau đó (về cơ bản, làm việc trên ảnh chụp nhanh của dữ liệu). – Alex

+0

Lưu ý rằng đó là những gì tôi hy vọng truy vấn 'Into Min (p.ZoneMin)' ban đầu của tôi sẽ tối ưu hóa, khi phần SQL của truy vấn bây giờ giống nhau. Có lẽ JITter có thể vẫn thấy điều đó, nhưng LINQPad's/o + thì không. –

+0

Và trong khi bạn chỉ tổng hợp với các hàm SQL hỗ trợ nó sẽ thích hợp hơn để thực hiện "nhóm theo một thủ thuật liên tục" để có được cơ sở dữ liệu để thực hiện tập hợp. –

Trả lời

0

Để trả lời câu hỏi rộng hơn của tôi: Aggregate có bị hỏng để tạo các truy vấn SQL riêng biệt không có giao dịch không? Tất cả LINQ có thể gây ra điều đó nếu bạn không cẩn thận điều chỉnh các truy vấn của mình để chỉ tạo ra một SELECT và điều đó có thể không thực hiện được mà không phải "từ bỏ", truy xuất kết quả lớn hơn trong một truy vấn và sau đó sử dụng LINQ-to-Objects để tổng hợp hoặc xử lý dữ liệu khác. This 'query' chẳng hạn.

Vì vậy, nói chung, người lập trình đảm bảo giao dịch được thêm vào xung quanh các truy vấn LINQ có thể gây ra nhiều truy vấn. Chúng ta chỉ cần biết chắc chắn các truy vấn LINQ nào có thể chuyển thành nhiều truy vấn SQL.

1

Alt. hough nó không sử dụng các từ khóa tổng hợp, bạn có thể làm nhiều chức năng trong một truy vấn bằng cách sử dụng cú pháp sau:

Dim query = From book In books _ 
    Group By key = book.Subject Into Group _ 
    Select id = key, _ 
     BookCount = Group.Count, _ 
     TotalPrice = Group.Sum(Function(_book) _book.Price), _ 
     LowPrice = Group.Min(Function(_book) _book.Price), _ 
     HighPrice = Group.Max(Function(_book) _book.Price), _ 
     AveragePrice = Group.Average(Function(_book) _book.Price) 

Hiện không có vẻ như là một vấn đề với việc thực hiện quy định tại khoản tổng hợp mặc dù. Hãy xem xét các truy vấn sau đây từ Northwind:

Aggregate o in Orders 
into Sum(o.Freight), 
Average(o.Freight), 
Max(o.Freight) 

này phát hành 3 yêu cầu cơ sở dữ liệu. Hai cái đầu tiên thực hiện các mệnh đề tổng hợp riêng biệt. Thứ ba kéo toàn bộ bảng trở lại máy khách và thực hiện Max trên máy khách thông qua LINQ to Objects.

+1

Vâng, và nếu bạn thay đổi nó thành 'Nhóm theo khóa = 0 vào nhóm' (và thả" id = key "không cần thiết) bạn sẽ nhận được mẹo" nhóm theo một hằng số "được mô tả trong câu trả lời cho câu hỏi mà tôi đã được gọi, cho phép tổng hợp trên toàn bộ bảng. –

+0

Trong mẫu của tôi, tôi muốn nhóm. Nếu bạn muốn nó trên toàn bộ bảng, sau đó lừa liên tục của bạn hoạt động tốt. –

+0

Tôi nghĩ * điểm sau của bạn có liên quan đến loại 'Freight' được xem là, và vì lý do nào đó, LINQ có nghĩa là' MAX' của SQL có thể trả về một giá trị khác với cái mà nó nghĩ 'Max' sẽ trả về. Nhưng các yêu cầu cơ sở dữ liệu _3 __separate__ là câu hỏi của tôi. –