2008-10-14 9 views
9

Trong một LINQ to SQL lớp, tại sao các thuộc tính được tạo ra từ các phím nước ngoài EntitySet đối tượng, mà thực hiện IEnumerable, trong khi đó các đối tượng trên DataContextTable đối tượng mà thực hiện IQueryable?EntitySet vs hiệu suất truy vấn Table trong LINQ2SQL

EDIT: Để làm rõ, dưới đây là ví dụ minh họa những gì tôi đang cố gắng hiểu. Ví dụ này:

ctx.Matches.Where(x => x.MatchID == 1).Single() 
      .MatchPlayers.Max(x => x.Score); 

lượt truy cập cơ sở dữ liệu hai lần nơi như:

ctx.MatchPlayers.Where(x => x.MatchID == 1) 
       .Max(x => x.Score); 

chỉ chạy 1 truy vấn. Dưới đây là những dấu vết:

exec sp_executesql N'SELECT [t0].[MatchID], [t0].[Date] 
FROM [dbo].[Matches] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 
exec sp_executesql N'SELECT [t0].[MatchID], [t0].[PlayerID], [t0].[Score] 
FROM [dbo].[MatchPlayers] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 

exec sp_executesql N'SELECT MAX([t0].[Score]) AS [value] 
FROM [dbo].[MatchPlayers] AS [t0] 
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1 
go 

đó cũng cho thấy rằng, thậm chí tệ hơn, tối đa được thực hiện ở mức độ # C hơn là trong cơ sở dữ liệu.

Tôi biết rằng lý do điều này xảy ra là sự khác biệt giữa IQueryable s và IEnumerable s, vậy tại sao không đối tượng MatchPlayers trong ví dụ đầu tiên thực hiện các giao diện IQueryable để có được những lợi ích tương tự như ví dụ sau.

Trả lời

1

Bảng có hiệu quả là một vấn đề khái niệm - chúng thực sự tồn tại trên máy chủ, vì vậy bạn cần truy vấn để nhận các mục nhập. Các mục nhập khóa ngoài là các mục nhập thực sự được truy vấn bởi một truy vấn khác, do đó, tại thời điểm đó chúng có sẵn cục bộ. Đó là một mô tả khá len, nhưng hy vọng nó vượt qua khái niệm chung.

3
ctx.Matches.Where(x => x.MatchID == 1).Single() 

Single() trả về kết quả trùng khớp, không phải là IQueryable (Match).

Chỉ cần đẩy đơn() ra đến bước cuối cùng:

ctx.Matches 
    .Where(m => m.MatchID == 1) 
    .Select(m => m.MatchPlayers.Max(mp => mp.Score)) 
    .Single(); 

gì truy vấn này cho thấy là, rằng đó là ok để sử dụng tài sản MatchPlayers trong một truy vấn. Mà giải quyết của tôi giải thích câu hỏi của người hỏi - "Tại sao tôi không thể sử dụng một EntitySet trong một truy vấn?", Bạn có thể.

0

Đây là addressed on the MSDN forums. Ý chính của lý luận là rất khó để theo dõi các đối tượng đã thêm và bị loại bỏ trong khi thực hiện các truy vấn đối với cơ sở dữ liệu. Thay vào đó, EntitySet là một bản sao cục bộ của các đối tượng liên quan mà bạn có thể thao tác. Thật không may, như bạn nhận thấy, điều này có tác dụng phụ của các biểu thức biến thành LINQ to Objects calls thay vì LINQ to SQL hoạt động tốt hơn.