2010-07-30 33 views
10

Tôi đang tìm quy tắc để gọi số ToList/ToArray/MemoizeAll(Rx) trên IEnumerables, trái ngược với việc trả lại truy vấn khi trả lại IEnumerable.Quy tắc ngón tay cái khi nào cần gọi ToList khi trả về kết quả LINQ

Thường thì tôi thấy tốt hơn là chỉ trả lại truy vấn và để người gọi quyết định xem danh sách có cần hay không, nhưng đôi khi nó có thể quay lại và cắn bạn ở phía sau do tính chất lười biếng của LINQ.

Tôi muốn thu thập những nguyên tắc như:

Gọi ToList nếu:

  • bạn tạo đối tượng mới
  • bạn có tác dụng phụ trong truy vấn của bạn
  • (ví dụ như trong một lựa chọn.)

Nếu không, hãy trả lại truy vấn

+4

Bạn hiếm khi (không bao giờ?) Có tác dụng phụ trong truy vấn của mình. –

Trả lời

23

Trước hết, bạn KHÔNG BAO GIỜ có tác dụng phụ trong truy vấn. Đó là một thực hành tồi tệ nhất. Truy vấn phải trả lời một câu hỏi, không tạo ra hiệu ứng.

Câu trả lời cho câu hỏi của bạn là: trả về truy vấn khi người gọi mong đợi một truy vấn; trả về một danh sách khi người gọi mong đợi một danh sách. Khi bạn thiết kế phương pháp của mình, hãy quyết định những gì người gọi có nhiều khả năng muốn, thực hiện điều đó và sau đó tài liệu nó.

Khi xem xét liệu người gọi muốn một truy vấn hoặc một danh sách, nghĩ về sự khác biệt giữa các truy vấn và danh sách:

  • truy vấn luôn up-to-date. Nếu các đối tượng/cơ sở dữ liệu/bất cứ điều gì truy vấn truy vấn chống lại thay đổi nội dung của nó, thì kết quả truy vấn sẽ thay đổi nếu bạn chạy lại truy vấn. Danh sách không thay đổi nội dung của chúng và do đó danh sách bị lỗi thời. Nếu người gọi của bạn yêu cầu dữ liệu mới nhất thì hãy cung cấp cho họ một truy vấn. Nếu họ yêu cầu ảnh chụp nhanh dữ liệu mà họ có thể kiểm tra lúc rảnh rỗi thì hãy cung cấp cho họ danh sách.

  • truy vấn có khả năng tốn kém để thực thi để có được kết quả của chúng. Danh sách có giá rẻ để có được kết quả của họ. Nếu người gọi có khả năng muốn thẩm vấn kết quả nhiều lần và hy vọng sẽ nhận được kết quả tương tự mỗi lần sau đó cung cấp cho họ một danh sách.

  • Xây dựng truy vấn là nhanh. Thực hiện truy vấn để tạo danh sách là chậm. Danh sách luôn thu được tất cả kết quả của truy vấn. Người gọi có thể muốn hạn chế hơn nữa truy vấn, bằng cách nói, chỉ lấy mười phần tử đầu tiên. Nếu người gọi không muốn hoặc cần phải thực hiện các chi phí của iterating hoàn toàn trên toàn bộ truy vấn sau đó cung cấp cho họ một truy vấn; không đưa ra quyết định đó thay mặt họ và đưa cho họ một danh sách.

  • truy vấn là nhỏ. Danh sách là lớn. Nhiều truy vấn có thể được lặp lại trên n mục trong không gian O (1); một danh sách có n mục chiếm không gian O (n). Nếu tập hợp kết quả là rất lớn thì việc đặt nó vào một danh sách có lẽ là không hiệu quả.

  • v.v.

Không có câu trả lời dễ dàng. Câu trả lời giống như câu trả lời cho bất kỳ vấn đề thiết kế nào khác: Hãy xem xét tất cả ưu và khuyết điểm của từng giải pháp có thể trong ngữ cảnh của những gì có khả năng nhất được người dùng muốn sử dụng, sau đó chọn giải pháp thỏa hiệp hợp lý.

3

Return ToList nếu:

  • Bạn không muốn hoặc chăm sóc cho đánh giá truy vấn lười biếng.

Edit:

Ngoài ra, sự trở lại ToList nếu:

  • Bạn đang sử dụng một số loại LINQ to SQL khuôn khổ (LLBLGen, EF, vv), và bạn cần phải làm phẫu thuật trong danh sách không thể dịch sang SQL theo khuôn khổ.
+0

+1 để chỉnh sửa. Đặc biệt là nếu các hoạt động tiếp theo sẽ khiến cơ sở dữ liệu bị truy cập nhiều lần bởi cùng một truy vấn. Sử dụng trình lược tả máy chủ SQL để xác định nơi sử dụng 'ToList()'. – Necros

1

bạn ToList() khi bạn muốn danh sách các đối tượng cho kết quả của mình.

+0

+1: Tôi không nghĩ nó có thể tốt hơn điều này như một hướng dẫn chung. –

+0

@Lasse: Tôi có. Câu trả lời này không giải thích * khi * chúng tôi muốn có một 'Danh sách '. –

+1

Vì có hàng triệu trường hợp sử dụng mà bạn muốn sử dụng một 'Danh sách ' và một triệu trường hợp sử dụng (trông kỳ lạ như nhau), nơi bạn không muốn sử dụng nó. Nó hoàn toàn cụ thể cho kịch bản trong tầm tay. Hướng dẫn khi sử dụng biến là gì? Hướng dẫn khi sử dụng chuỗi là gì? Bạn không thể thực sự tạo ra một hướng dẫn mà nói như vậy. Bây giờ, tôi đồng ý, bạn có thể mô tả các tính năng của một danh sách, và sau đó nói "khi bạn cần bất kỳ điều này, bạn muốn sử dụng một danh sách", nhưng anh ta yêu cầu hướng dẫn về * trả về dữ liệu *. Bạn không thể, bởi vì cho dù bạn muốn sử dụng một danh sách hay không là không tùy thuộc vào bạn. –

2

Sử dụng danh sách phát nếu bạn cần chạy các hàm tùy chỉnh trên dữ liệu được LINQ to SQL trả về.

2

Sử dụng ToList trước khi bạn thoát khỏi using khối giữ DataContext.

Trả về truy vấn khi người gọi có khả năng/bắt buộc cung cấp tiêu chí lọc bổ sung sẽ được chỉ mục sử dụng để giảm # hàng kết quả và/hoặc cơ sở dữ liệu IO.

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