2013-08-13 37 views
5

Sử dụng khung thực thể Tôi chọn một số dữ liệu từ một bảng và lặp lại nó với vòng lặp foreach. Tôi tự hỏi khi nào dữ liệu được truy vấn trong các ví dụ sau?iterating over DbSet <TEntity> vs IQueryable <out T>

Ví dụ 1.

var countries = db.WorldCountries; 
foreach(var item in countries) 
{ 
    Console.WriteLine("Country: {0}", item.Country); 
} 

Ví dụ 2.

var countries = db.WorldCountries.Where(t => t.Country == "Country Name"); 
foreach(var item in countries) 
{ 
    Console.WriteLine("Country: {0}", item.Country); 
} 

Trong ví dụ đầu tiên, countriesDbSet<WorldCountries> Trong ví dụ thứ hai, countriesIQueryable<out WorldCountries>.

Nếu không có .ToList() trong ví dụ trên, dữ liệu được truy xuất như thế nào? Toàn bộ tập dữ liệu có được truy xuất khi vòng lặp foreach bắt đầu (như thể .ToList() được gọi ở đầu vòng lặp đầu tiên) hoặc truy vấn được phát hành cho cơ sở dữ liệu trên mỗi lần lặp của vòng lặp.

Cảm ơn.

Trả lời

8

Trong cả hai ví dụ, IQueryable<WorldCountries> được biên dịch thành SQL và được thực thi tại thời điểm bạn nhập foreach (khi foreach gọi GetEnumerator). Vì vậy, bạn nhận được kết quả từ db ngay trước lần lặp đầu tiên, không từng mảnh một trên mỗi lần lặp (kết quả đến thông qua một DataReader để chuyển dữ liệu thực tế có thể được thực hiện từng phần cho mỗi lần lặp lại nhưng ý tôi là, không phải là một truy vấn SQL riêng biệt trên mỗi lần lặp).

Lưu ý rằng DbSet<T> cũng triển khai IQueryable<WorldCountries>, vì vậy cả hai ví dụ của bạn đều làm việc giống nhau, ngoại trừ trường hợp thứ hai xảy ra bao gồm mệnh đề where.

Khi bạn thêm .ToList, nó lặp lại và điền vào danh sách trước khi quay trở lại, vì vậy trong trường hợp đó bạn chuyển tất cả dữ liệu cần thiết từ db trước khi chuyển sang câu lệnh tiếp theo.

+0

Bạn có chắc chắn rằng việc truyền dữ liệu được thực hiện từng mảnh, nếu bạn có bất kỳ tham chiếu nào về điều đó không? Tôi rất tò mò về điều này –

+5

Tôi đã có thể xác nhận rằng bạn là chính xác, nó thực sự kéo dữ liệu theo lô, không phải tất cả cùng một lúc. Tôi đã viết một bài kiểm tra bằng cách lặp qua một dbset lớn - một phần thông qua tôi giết kết nối db đó, và như mong đợi một lỗi đã được ném. –

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