2010-10-15 41 views
6

Tôi có một phương pháp, mà trả về một nhóm các tài khoảnReturn Thuộc tính cho Bộ sưu tập từ LINQ Query

Public Shared Function GetAllNotesByUser(ByVal UserID As Guid) As Account (??) 
    Using db As New MyEntity 
     Dim query= (From A In db.Account _ 
        Where A.aspnet_Users.UserId = UserID _ 
        Select A) 
     Return query 
    End Using 
End Function 

sau đó tôi muốn chuyển thông tin này đến chức năng khác để tính toán tổng số cho tất cả các tài khoản trong bộ sưu tập. Có thực hành tốt nhất để trả về một danh sách chung, tôi chỉ không chắc chắn những gì làm việc tốt nhất với LINQ và khung thực thể.

Trả lời

7

Khi truyền kết quả truy vấn LINQ từ phương thức theo cách này, lựa chọn tốt nhất cho loại trả về là IEnumerable(Of T) cho LINQ đối tượng hoặc IQueryable(Of T) cho các nhà cung cấp LINQ khác. Trong trường hợp này, có vẻ như Account là loại như vậy IEnumerable(Of Account) hoặc IQueryable(Of T) tùy thuộc vào loại truy vấn được đề cập.

+1

lựa chọn tốt nhất là 'IEnumerable' trừ khi lựa chọn tốt nhất là 'IQueryable'. ;) –

+0

@Kirk, đúng vậy. Quên về trường hợp đó fro không LINQ đối với các truy vấn đối tượng – JaredPar

2

Loại tốt nhất là

IEnumerable<Account> 

hoặc cú pháp correspounding trong VB: P

Trên thực tế, tất cả các chức năng LINQ (.Where(), .Distinct() vv) là phương pháp khuyến nông để IEnumerable<T>, để tôi nghĩ rằng nó là thực hành tốt để tiếp tục chuỗi theo cùng một cách.

+0

Tôi đã tìm kiếm MSDN, nhưng phải tìm ở địa điểm sai. Làm thế nào để bạn biết rằng WHERE() và Distinct() là các phương pháp mở rộng của IEnumerable . Tôi không hỏi bạn, tôi chỉ tự hỏi nơi để xem xét thời gian tới tôi có một câu hỏi tương tự. –

+0

@Travis không thành vấn đề. Trên thực tế trong MSDN, nó không phải là thực sự rõ ràng "nơi" những phương pháp mở rộng được xác định ... nhưng bạn có thể tìm thấy danh sách trên trang cho 'IEnumerable ' (phiên bản chung): http://msdn.microsoft.com/ en-us/library/9eekhta0.aspx. Có một biểu tượng nhỏ cho biết đó là một phương pháp mở rộng ...và khi bạn nhấp vào một trong số chúng, bạn có thể thấy trong đó không gian tên nó sống ... Nghĩa là, để sử dụng bất kỳ phương pháp mở rộng LINQ nào, bạn cần phải có 'using System.Linq;' ở đầu tệp của bạn. – tsimbalar

+0

Ồ, và cách tôi biết, chỉ vì VS luôn thêm một tham chiếu đến 'System.Linq' và Intellisense chỉ gợi ý chúng :-). Behing mui xe, tất cả các "linq" biểu thức giống như truy vấn được chuyển đổi thành chuỗi các phương pháp mở rộng LINQ. – tsimbalar

0

Câu hỏi bạn cần đặt ra là: "Khi nào tôi cần SQL để thực sự được thực thi?" Trong LINQ, đó là sự khác biệt giữa việc hoãn lại và thực thi ngay lập tức. Bất kỳ phương thức nào trả về số IEnumerable<> đều phải thực hiện truy vấn để nhận kết quả. Mặt khác, IQueryable<>, trì hoãn việc thực hiện truy vấn cho đến khi phương thức trả về số IEnumerable<> được gọi chống lại nó. Trong ví dụ mà bạn cung cấp, nó có thể nhanh hơn để vượt qua kết quả của GetAllNotesByUser chức năng như một IQueryable<>, do đó bạn chạy một truy vấn duy nhất thay vì hai:

public static IQueryable<Account> GetAllNotesByUser(Guid UserId) 
{ 
    ... 
} 

Có thể có tình huống mà bạn cần phải liệt kê các kết quả của GetAllNotesByUser mà không thực hiện bất kỳ thao tác bổ sung nào. Trong những trường hợp đó, hãy nhớ rằng bạn có thể gọi 'ToList() `để bắt buộc thực hiện truy vấn.

var result = GetAllNotesByUser(<guid>).ToList(); 
+0

' AsEnumerable' không bắt buộc thực hiện truy vấn: http://stackoverflow.com/questions/3389855/am-i-understandstanding-linq-to-sql-asenumerable – nawfal

+0

Có, bạn là chính xác. ToList() sẽ buộc thực thi. –

+0

Neil, sau đó chỉnh sửa câu trả lời của bạn. Nó đảm bảo một downvote nếu không :) – nawfal

1

Có một câu trả lời tốt here trên IEnumerable<T> vs IQueryable<T>.

Tôi sẽ sử dụng IQueryable(Of T) nếu bạn muốn giới hạn thêm tập hợp trong trình gọi của phương thức, ví dụ với mệnh đề WHERE. Nếu không, tôi sẽ sử dụng IEnumerable(Of T) nếu tất cả người gọi biết rằng họ cần thực hiện ToList() trên kết quả nếu họ lập kế hoạch lặp lại nhiều lần (nếu không bạn sẽ thực hiện nhiều cuộc gọi đến cơ sở dữ liệu). Nếu người gọi không biết, tôi có thể sử dụng ICollection(Of T) và thực hiện ToList() trong chính phương thức đó.

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