Почему это дополнительное объединение увеличивает количество запросов? - PullRequest
1 голос
/ 26 мая 2011

У меня проблемы с поиском эффективного запроса LINQ-to-SQL.Я пытаюсь сделать что-то вроде этого:

from x in Items
select new
{
    Name = x.Name
    TypeARelated = from r in x.Related
                   where r.Type == "A"
                   select r
}

Как и следовало ожидать, он генерирует один запрос из таблицы «Items» с левым соединением в таблице «Related».Теперь, если я добавлю еще несколько похожих строк ...

from x in Items
select new
{
    Name = x.Name
    TypeARelated = from r in x.Related
                   where r.Type == "A"
                   select r,
    TypeBRelated = from r in x.Related
                   where r.Type == "B"
                   select r
}

В результате выполняется аналогичный запрос с первой попытки, за которым следует отдельный запрос к таблице "Related" для каждой записи в "Предметы".Есть ли способ обернуть все это в один запрос?Что будет причиной этого?Заранее благодарим за любую помощь, которую вы можете предоставить.

Ответы [ 2 ]

3 голосов
/ 26 мая 2011

Приведенный выше запрос, если он написан непосредственно на SQL, будет написан так (псевдокод):

SELECT 
    X.NAME AS NAME,
    (CASE R.TYPE WHEN A THEN R ELSE NULL) AS TypeARelated,
    (CASE R.TYPE WHEN B THEN R ELSE NULL) AS TypeBRelated
FROM Items AS X
JOIN Related AS R ON <some field>

Однако linq-to-sql не так эффективен, как вы пояснили, он делаетприсоединиться, а затем перейти к индивидуальному сравнению каждой записи.Лучше было бы использовать два запроса linq, аналогичные вашему первому примеру, которые генерировали бы два запроса SQL.Затем используйте результаты двух запросов linq и присоединитесь к ним, что не приведет к созданию оператора SQL.Этот метод ограничил бы количество запросов, выполняемых в SQL, до 2.

Если число условий ierType == "A" и т. Д., Со временем будет увеличиваться или будут добавлены другие условия,Вам лучше использовать хранимую процедуру, которая всегда будет одним SQL-запросом.

Hasanain

1 голос
/ 26 мая 2011

Вы можете использовать готовую загрузку, чтобы выполнить одно соединение на сервере, чтобы увидеть, помогает ли это.Попробуйте это.

using (MyDataContext context = new MyDataContext())
{
    DataLoadOptions options = new DataLoadOptions();
    options.LoadWith<Item>(i => i.Related);
    context.LoadOptions = options;

    // Do your query now.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...