Linq to Entities и LEFT OUTER JOIN выпускают с MANY: 1 отношения - PullRequest
7 голосов
/ 22 марта 2010

Может кто-нибудь сказать мне, почему Linq to Entities переводит многие в 1 отношения в left outer join вместо inner join? Поскольку существует референтное ограничение для самой БД, которое гарантирует наличие записи в нужной таблице, поэтому вместо нее следует использовать inner join (и это будет работать намного быстрее)

Если бы отношение было много к 0..1 left outer join было бы правильным.

Вопрос

Можно ли написать LINQ таким образом, чтобы он преобразовывался в inner join, а не left outer join. Это значительно ускорило бы выполнение запросов ... Я раньше не использовал eSQL, но было бы разумно использовать его в этом случае? Решит ли это мою проблему?

Редактировать

Я обновил свои теги, чтобы включить технологию, которую я использую в фоновом режиме:

  • Entity Framework V1
  • Devart dotConnect для Mysql
  • База данных MySql

Если бы кто-то мог проверить, верно ли то же самое на сервере Microsoft SQL, это также дало бы мне некоторое представление, если это проблема Деварта или это общая функциональность L2EF ... Но я подозреваю, что EF является виновником здесь.

1 Ответ

2 голосов
/ 26 марта 2010

Я немного поработал над провайдером фреймворка сущностей и посмотрел на это.Я считаю, что сам провайдер не имеет выбора в данной ситуации.Дерево команд создается структурой сущностей и предоставляет его поставщику для построения SQL.Здесь это полное предположение, но, возможно, причина, по которой оно генерирует LEFT OUTER соединение в этой ситуации, заключается в том, что структура сущностей не знает, что в базе данных существует референтное ограничение.Например, я могу пойти и разобраться с моделью сущностей после ее создания из базы данных и добавить / изменить ограничения, которые не отражают то, что делает база данных.Возможно, по этой причине дизайнеры решили не рисковать и создать соединение LEFT OUTER «на всякий случай».

Тем не менее, я считаю, что вы можете получить внутреннее соединение.Например, следующее привело к тому, что провайдер создал LEFT OUTER соединение:

var res2 = from a in ent.answers
           select new
           { a.Answer1, a.user.UserName };

Тем не менее, следующие результаты в INNER соединении:

res2 = from a in ent.answers
       join u in ent.users
       on a.UserID equals u.PK
       select new { a.Answer1, u.UserName };

Кроме того, был получен следующий объект SQLвнутреннее соединение:

ObjectQuery<DbDataRecord> dr = ent.CreateQuery<DbDataRecord>( 
         "SELECT a.answer1, u.username " +
         "FROM answers as a inner join users as u on a.userid = u.pk" );
...