Looking at the profiler I see a few differences. The second query which uses the include will in fact return data from related to the secondary table CountryCodes. This part makes sense to me. I don't however understand why this query has two joins. First it does a regular inner join between CountryCodes ands CountyCodeTypes (on the foreign key) which I would think be sufficient to return everything that the include requires. However it then does another outer join. Why?
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;
resulting 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
Also, is it fair to say that I should use the .Include only when I actually need data in the foreign key table to be populated in my result, otherwise use the join? In other words I shouldn't use the .Include as the means to the join because the navigational properties know how to join entities for me based on the keys.