I’m not quite understanding why the Include clause on this query
from m in _cmsDb.Matters.Include("MatterContacts.ClientContact.Name")
where m.CLIENT_CODE == clientCode && m.MATTER_CODE == matterCode
from mc in m.MatterContacts
select mc.ClientContact;
and the subsequent navigation property references made on the resultant ClientContact entities is not satistifed with a single SQL call. The Matter entity has many MatterContact and each one of those links to a single ClientContact and this last entity has a navigation property called Name which links to a Name entity.
When tracing the SQL, I see that my Include clause has caused joins to happen all the way down to the table containting the Name entity. Here is an extraction of the joins I am seeing:
HBM_MATTER INNER JOIN [dbo].[HBA_MATTER_CONT] AS [Extent2] ON [Extent1].[MATTER_UNO] = [Extent2].[MATTER_UNO]
LEFT OUTER JOIN (... FROM [dbo].[HBA_CLIENT_CONT] AS [HBA_CLIENT_CONT]) AS [Extent3] ON [Extent2].[CONTACT_UNO] = [Extent3].[CONTACT_UNO])
FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent4] ON [Extent3].[NAME_UNO] = [Extent4].[NAME_UNO]
So I see the joins happening all the way through the hierarchy. However, when I access the properties of the Name entity (e.g. .Name.FirstName), I see additional SQL calls to look up the name.
e.g.
...
FROM (SELECT ... FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent1]
WHERE [Extent1].[NAME_UNO] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=204629
I would have thought that the Include would have brought the Name entity into memory for the returned ClientContact objects. But the trace would indicate otherwise.
Common rule of
Includeis that it works only if you don’t use projection or custom join. I think the real rule is: Shape of the query mustn’t change. If you useIncludeonMatterI expect you must also returnMatterinstances to let the magic do its work. You are usingIncludeonMatterbut selectClientContract– the shape of the query has changed.What happens if you try this: