ICollection <T> Danh sách Vs <T> trong Khung thực thể


114

Tôi chỉ xem một vài webcast trước khi bắt đầu thiết kế một vài ứng dụng Entity Framework. Tôi thực sự đã không đọc nhiều tài liệu đó và tôi cảm thấy như tôi đang đau khổ vì nó bây giờ.

Tôi đã sử dụng List<T>trong các lớp học của mình, và nó đã hoạt động tốt.

Bây giờ tôi đã đọc một số tài liệu và nó nói rằng tôi nên sử dụng ICollection<T>. Tôi đã thay đổi điều này và nó thậm chí không gây ra thay đổi bối cảnh mô hình. Điều này có phải bởi vì cả hai List<T>ICollection<T>kế thừa IEnumerable<T>, và đó là những gì thực sự cần thiết cho EF?

Tuy nhiên, nếu đúng như vậy, tại sao tài liệu EF không nêu rõ điều đó IEnumerable<T>thay vì yêu cầu ICollection<T>?

Trong mọi trường hợp, có bất kỳ nhược điểm nào đối với những gì tôi đã làm hay tôi nên thay đổi nó?

Câu trả lời:


113

Entity Framework sẽ sử dụng ICollection<T>vì nó cần hỗ trợ các Addhoạt động không phải là một phần của IEnumerable<T>giao diện.

Cũng lưu ý rằng bạn đang sử dụng ICollection<T>, bạn chỉ đơn thuần thể hiện nó dưới dạng List<T>triển khai. List<T>mang lại cùng với nó IList<T>, ICollection<T>IEnumerable<T>.

Đối với sự thay đổi của bạn, hiển thị qua giao diện là một lựa chọn tốt, mặc dù có List<T>tác dụng. Giao diện xác định hợp đồng nhưng không thực hiện. Việc triển khai có thể thay đổi. Trong một số trường hợp, có lẽ việc triển khai có thể là một HashSet<T>ví dụ. (Nhân tiện, đây là tư duy mà bạn có thể sử dụng cho nhiều thứ hơn là Entity Framework. Một phương pháp hướng đối tượng tốt là lập trình theo hướng giao diện chứ không phải việc triển khai. Việc triển khai có thể và sẽ thay đổi.)


2
Vì vậy .... chỉ để tôi hiểu thêm một chút - Danh sách kế thừa IList, kế thừa ICollection, kế thừa IEnumerable?
wil

3
Vâng, đó là dây chuyền. List<T>phải thực hiện từng trong những giao diện ( IList<T>, ICollection<T>, IEnumerable<T>) vì hệ thống phân cấp thừa kế. Hoàn thành, IList<T>cũng nhặt không chung chung IList, ICollectionIEnumerablegiao diện.
Anthony Pegram

Cảm ơn bạn ... Một số tính năng Ixxx vẫn chưa hiểu tôi! Tuy nhiên, bạn đã có lý, tuy nhiên, một điều cuối cùng làm tôi khó chịu, nếu Ixx của Ixx kế thừa IEnumerable, thì làm thế nào nó thêm vào IEnumerable nếu Ienumerable chỉ được đọc? ... Nếu nó quá phức tạp, đừng lo lắng, khi tôi có một chút thời gian, tôi sẽ thử bắn lên phản xạ!
wil

10
Các hoạt động Linq thông thường không thêm hoặc thay đổi mọi thứ, chúng chỉ đơn giản là lọc, nhóm, dự án, v.v. Các chuỗi chỉ đọc, chỉ chuyển tiếp là tất cả những gì cần thiết để hỗ trợ các hoạt động đó. Khi bạn có nhà cung cấp Linq, chẳng hạn như Entity Framework giải quyết vấn đề liên tục dữ liệu, khả năng Thêm là một lợi ích đáng kể yêu cầu giao diện mạnh mẽ hơn, đó là thứ mời tham ICollection<T>gia nhóm (và giao diện này mang theo nó IEnumerable<T>, vì vậy " "Hoạt động của Linq vẫn còn hiệu lực).
Anthony Pegram

@AnthonyPegram: Tôi nghĩ hoàn toàn không chính xác khi nói rằng cả ba giao diện phải được triển khai. Vì IList <T> kế thừa ICollection <T> kế thừa IEnumerable <T>, nên việc List <T> chỉ cần thực hiện IList <T> là đủ.
CJ7

51

Họ chọn giao diện mà họ đã làm vì nó mang lại sự trừu tượng dễ hiểu đối với các truy vấn ma thuật mà Entity Framework thực hiện khi bạn sử dụng Linq.

Đây là sự khác biệt giữa các giao diện:

  • IEnumerable<T> là chỉ đọc
  • Bạn có thể thêm và xóa các mục vào một ICollection<T>
  • Bạn có thể thực hiện truy cập ngẫu nhiên (theo chỉ mục) vào một List<T>

Trong số đó, ICollectionIEnumerableánh xạ tốt các hoạt động cơ sở dữ liệu, vì truy vấn và thêm / xóa các thực thể là những việc bạn có thể làm trong DB.

Truy cập ngẫu nhiên theo chỉ mục cũng không ánh xạ, vì bạn phải có một kết quả truy vấn hiện có để lặp lại hoặc mỗi truy cập ngẫu nhiên sẽ truy vấn lại cơ sở dữ liệu. Ngoài ra, chỉ mục sẽ ánh xạ tới cái gì? Số lượng hàng? Không có nhiều truy vấn số hàng mà bạn muốn thực hiện và nó hoàn toàn không hữu ích trong việc xây dựng các truy vấn lớn hơn. Vì vậy, họ chỉ đơn giản là không ủng hộ nó.

ICollection<T> được hỗ trợ và sẽ cho phép bạn cả truy vấn và thay đổi dữ liệu, vì vậy hãy sử dụng điều đó.

Lý do List<T>hoạt động để bắt đầu là vì việc triển khai EF cuối cùng trả về một kết quả. Nhưng đó là ở cuối chuỗi truy vấn của bạn, không phải ở đầu. Vì vậy, việc tạo các thuộc tính của bạn ICollection<T>sẽ làm rõ ràng hơn rằng EF tạo ra một loạt SQL và chỉ trả về một List<T>ở cuối, thay vì thực hiện các truy vấn cho mỗi cấp độ Linq mà bạn sử dụng.


8

ICollection khác với IEnumerable ở chỗ bạn thực sự có thể thêm các mục vào bộ sưu tập, trong khi với IEnumerable, bạn không thể. Vì vậy, trong các lớp POCO của bạn, ví dụ, bạn muốn sử dụng ICollection nếu bạn định cho phép thêm bộ sưu tập vào. Làm ảo ICollection để hưởng lợi từ việc tải chậm.


1
Tôi muốn hiểu - bạn có thể thực hiện các thao tác tương tự (và hơn thế nữa!) Với Danh sách <T>. Tại sao ICollection <T>? Tại sao không phải là Danh sách <T>? Trông đơn giản và mạnh mẽ hơn.
monstro

Danh sách <T> Thực hiện ICollection và IEnumerable. Hoạt động nhiều hơn nhưng đi kèm với đó là chi phí cao hơn.
IronAces

4

Mặc dù câu hỏi đã được đăng cách đây nhiều năm, nhưng nó vẫn có giá trị khi ai đó đang tìm kiếm kịch bản tương tự.

Có một bài báo gần đây về CodeProject [2015] giải thích sự khác biệt rất chi tiết và biểu diễn đồ họa với mã mẫu . Nó không được tập trung trực tiếp tại EF nhưng vẫn hy vọng nó sẽ giúp ích nhiều hơn:

List vs IEnumerable vs IQueryable vs ICollection vs IDictionary

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.