LINQ2SQL - дополнительные вопросы о том, когда вместо Inner Join создается выражение Cross с предложением where - PullRequest
0 голосов
/ 16 марта 2011

Это вопрос, состоящий из двух частей, и для образовательных целей, а не для поиска решения проблемы.

Я уже видел это и понимаю, что это очень похоже на мой вопрос

LINQ2SQL - перекрестное соединение отправляется, когда я хочу внутреннее соединение

Но я надеюсь, что вы, гуру LINQ и SQL, получите больше информации о , почему перекрестное соединение создается вместо внутреннего соединения в LINQ2SQL . Кроме того, может кто-нибудь объяснить, как SQL Server выбирает план выполнения (или ссылку на дополнительную информацию), поскольку оба этих запроса генерируют один и тот же план ? Из того, что я понимаю, это означает, что производительность запросов одинакова.

Я создал небольшой пример, который запускает два выражения LINQ в моей базе данных, которые генерируют эти два разных SQL-запроса.

Для тех, кто не хочет беспокоиться, вот мой пример диаграммы БД: http://dl.dropbox.com/u/13256/Screen%20shot%202011-03-16%20at%2011.41.56%20AM.png

Вот два запроса: Перекрестное соединение с пунктом «Где»

var q = from item in context.Items
join i_mem in context.Memberships on new { item_id = item.ID, user_id = 
current_user_id.Value } equals new { item_id = i_mem.RelatedItemID, user_id = 
i_mem.RelatedUserID } into sq_i_m
from im in sq_i_m.DefaultIfEmpty()
join i_cat in context.Categories on item.RelatedCategoryID equals i_cat.ID 
into sq_i_cat
from proj in sq_i_cat
select item;

Внутреннее присоединение

from item in context.Items
join i_mem in context.Memberships on
new { item_id = item.ID, user_id = current_user_id.Value }
equals
new { item_id = i_mem.RelatedItemID, user_id = i_mem.RelatedUserID }
into sq_i_m
from im in sq_i_m.DefaultIfEmpty()
join i_cat in context.Categories on item.RelatedCategoryID equals i_cat.ID
select item

И здесь - это тестовая программа, которую вы хотели бы увидеть сами.

Спасибо всем за помощь.

Мустафа

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Это одно и то же, поэтому не имеет значения, какой из LINQ2SQL выдает.

inner join логически эквивалентно перекрестному соединению с фильтром предложения where, эквивалентным on предложения inner join.

Вот почему Sql Server генерирует тот же план запросов.

Для ясности, внутреннее соединение:

Select f1 
From T1 inner join T2 on T1.k = T2.k
where T1.f2 like 'X%'

То же, что и перекрестное соединение:

Select f1 
From T1 cross join T2 
where T1.k = T2.k
and T1.f2 like 'X%'

соответствует SQL в старом стиле:

Select f1 
From T1, T2 
where T1.k = T2.k
and T1.f2 like 'X%'
0 голосов
/ 16 марта 2011

Допустим, у вас есть текстовый текст с именем MyDataContext.

using(MyDataContext db = new MyDataContext())
{
  var q = db.Items.Where(x=> x.Categories.Name == "myCategory").Select(x=> x);
}

Это очень простой пример, но вам не нужно было выписывать объединение или подзапрос в синтаксисе TSQL.(Я ненавижу писать TSQL).

...