Глядя на профилировщик, я вижу несколько отличий. Второй запрос, который использует include, фактически вернет данные из вторичной таблицы CountryCodes. Эта часть имеет смысл для меня. Однако я не понимаю, почему этот запрос имеет два соединения. Во-первых, он выполняет обычное внутреннее соединение между CountryCodes и CountryCodeTypes (по внешнему ключу), которого, как мне кажется, будет достаточно, чтобы вернуть все, что требует include. Однако затем он выполняет другое внешнее соединение. Почему?
var query = from codes in base.context.CountryCodes
join codeTypes in base.context.CountryCodeTypes
on codes.CountryCodeTypeId equals codeTypes.CountryCodeTypeId
where codeTypes.CountryCodeTypeName == countryCodeType
select codes;
var query = from codes in base.context.CountryCodes.Include("CountryCodeType")
where codes.CountryCodeType.CountryCodeTypeName == countryCodeType
select codes;
результирующий sql:
FROM [dbo].[CountryCode] AS [Extent1]
INNER JOIN [dbo].[CountryCodeType] AS [Extent2] ON [Extent1].[CountryCodeTypeId] = [Extent2].[CountryCodeTypeId]
LEFT OUTER JOIN [dbo].[CountryCodeType] AS [Extent3] ON [Extent1].[CountryCodeTypeId] = [Extent3].[CountryCodeTypeId]
WHERE [Extent2].[CountryCodeTypeName] = @p__linq__0
Кроме того, справедливо ли сказать, что я должен использовать .Include только тогда, когда мне действительно нужны данные в таблице внешнего ключа, которые должны быть заполнены в моем результате, иначе используйте соединение? Другими словами, я не должен использовать .Include в качестве средства для соединения, потому что свойства навигации знают, как объединять сущности для меня на основе ключей.