Вопрос

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

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

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песок IEnumerables, так почему бы не MatchPlayers объект в первом примере реализует IQueryable интерфейс, чтобы получить те же преимущества, что и в последнем примере.

Это было полезно?

Решение

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

Другие советы

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

Single() возвращает Match, а не IQueryable(Match).

Просто нажмите Single() на последний шаг:

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top