42

Vì vậy, mô hình EF của tôi có mối quan hệ và theo những gì tôi đã thấy trong ví dụ, những mối quan hệ này nên được thực hiện với các thuộc tính ảo của ICollection.EF ICollection Vs Danh sách Vs IEnumerable Vs IQueryable

Ví dụ:

public class Task 
    { 
     public int Id { get; set; } 
     public string Description { get; set; } 
     public virtual ICollection<SubTask> { get; set; } 
    } 

Tôi đọc ở đâu đó rằng tôi nên sử dụng IEnumerable để ngăn chặn thực hiện chậm, đó là đúng? Điều đó có nghĩa là nếu các phương thức DAL của tôi trả về IEnumerable, vẫn là IQueryable, thì SQL sẽ được thực hiện tại thời điểm đó, và không phải tại thời điểm tôi gọi .TOList trong trang web.

Vì vậy, phương pháp hay nhất là gì? Tôi nên trở về cái gì? IEnumerable, List ?, IList, ICollection?

thx

+0

Tôi nghĩ rằng 'virtual' có trách nhiệm thực thi bị trì hoãn hay không, nhưng tôi có thể sai. – mfussenegger

+0

@mfussenegger virtual chỉ được sử dụng trên các khai báo có thể bị ghi đè –

Trả lời

60

IQueryable:

  • Query không được thực hiện cho đến khi bạn thực sự lặp qua các mặt hàng, có lẽ bằng cách thực hiện một .ToList() hoặc một foreach. Điều đó có nghĩa là bạn vẫn có thể thêm bộ lọc, chẳng hạn như Where().
  • Mở rộng IEnumerable

IEnumerable:

  • Forward-only danh sách các mục. Bạn không thể nhận được ở "mục 4" mà không qua các mục 0-3.
  • Danh sách chỉ đọc, bạn không thể thêm vào danh sách đó hoặc xóa khỏi danh sách đó.
  • Vẫn có thể sử dụng thực thi hoãn lại (IQueryable vẫn là một IEnumerable).

IList:

  • truy cập ngẫu nhiên vào danh sách đầy đủ
  • lẽ hoàn toàn trong bộ nhớ (? Không thực hiện chậm, nhưng ai mà biết được những gì lớp chính xác không mà thực hiện điều này)
  • Hỗ trợ thêm và xóa
  • Mở rộng IEnumerable và ICollection

ICollection:

  • Giữa IEnumerable và IList.
  • Mở rộng IEnumerable

Điều gì là "tốt nhất" tùy thuộc vào yêu cầu của bạn. Thông thường, mặc dù một IEnumerable là "đủ tốt" nếu bạn chỉ muốn hiển thị các mục. Ít nhất luôn sử dụng biến thể chung chung.

+3

Nếu bạn hiển thị thuộc tính điều hướng của mình dưới dạng IEnumerable , bạn sẽ không thể thêm các mục vào bộ sưu tập. –

+4

Tốt bị hỏng. Đối với việc thực hiện trì hoãn, truy vấn sẽ không được hình thành cho đến khi bạn gọi .GetEnumerator trên IEnumerable (tất cả các loại khác đều xuất phát từ). Nếu bạn sử dụng bất kỳ thứ gì ngoài IQueryable, tất cả các kết quả sẽ đến với máy khách và được lọc ở đó thay vì các bộ lọc đang được áp dụng ở cấp cơ sở dữ liệu. Bạn cần IQueryable để giữ lại cây biểu thức mà GetEnumerator sẽ sử dụng để tạo ra TSQL thích hợp. –

+1

cũng thấy http://stackoverflow.com/a/10113331/870291 – dotNETbeginner

1

Sự khác biệt trong trường hợp EF là IEnumerable không thực hiện truy vấn cho DB cho đến khi bạn thực sự liệt kê danh sách. Trong khi IList sẽ thực hiện truy vấn và tìm nạp các mục trong bộ nhớ. Tôi đã có một hành vi kỳ lạ với bộ nhớ đệm. Chaching IEnumarable không lưu trữ các mục mà thay vào đó là liệt kê chưa được tìm kiếm, mọi lúc tôi sẽ gọi bộ nhớ cache và lấy liệt kê cho một số mục đích, nó sẽ đi đến DB và thực hiện truy vấn, do đó, bộ nhớ đệm là vô dụng.Nhưng một ToList() trên liệt kê lấy các mục và lưu trữ các mục trong bộ nhớ cache, vì vậy chỉ có 1 chuyến đi đến DB cho việc này. Tìm thêm trong bài đăng này: http://www.dailycode.info/BlogV2/post/entityframework-adding-ienumerable-to-cache

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