EntitySet против производительности запросов таблиц в LINQ2SQL - PullRequest
9 голосов
/ 14 октября 2008

В классе LINQ to SQL, почему свойства, созданные из внешних ключей EntitySet объектов, которые реализуют IEnumerable, где в качестве объектов на DataContext являются Table объекты, которые реализуют IQueryable * * 1006

РЕДАКТИРОВАТЬ: Чтобы пояснить, вот пример, который иллюстрирует то, что я пытаюсь понять. Этот пример:

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

дважды попадает в базу данных, где:

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

запускает только 1 запрос. Вот следы:

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 #, а не в базе данных.

Я знаю, что причина этого заключается в разнице между IQueryable с и IEnumerable с, поэтому, почему объект MatchPlayers в первом примере не реализует интерфейс IQueryable, чтобы получить те же преимущества, что и последний пример.

Ответы [ 3 ]

3 голосов
/ 14 октября 2008
ctx.Matches.Where(x => x.MatchID == 1).Single()

Single () возвращает совпадение, а не IQueryable (совпадение).

Просто нажмите Single (), чтобы перейти к последнему шагу:

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

Этот запрос показывает, что в запросе можно использовать свойство MatchPlayers. Который отвечает на мою интерпретацию вопроса задающего - «Почему я не могу использовать EntitySet в запросе?», Вы можете.

1 голос
/ 14 октября 2008

Таблицы, по сути, являются концептуальным вопросом - они действительно существуют на сервере, поэтому вам нужно выполнить запрос для получения записей. Записи внешнего ключа на самом деле выбираются другим запросом, поэтому в этот момент они доступны локально. Это довольно неясное описание, но, надеюсь, оно превзойдет общую концепцию.

0 голосов
/ 24 февраля 2009

Это было адресовано на форумах MSDN . Суть рассуждений в том, что очень трудно отслеживать добавленные и удаленные объекты при выполнении запросов к базе данных. Вместо этого EntitySet является чем-то вроде локальной копии связанных объектов, которыми вы можете манипулировать. К сожалению, как вы заметили, это имеет побочный эффект от передачи выражений в вызовы LINQ to Objects вместо лучшего выполнения LINQ to SQL.

...