Reputation: 11468
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.
Upvotes: 0
Views: 253
Reputation: 364249
Common rule of Include
is 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 use Include
on Matter
I expect you must also return Matter
instances to let the magic do its work. You are using Include
on Matter
but select ClientContract
- the shape of the query has changed.
What happens if you try this:
ObjectQuery<ClientContract> query = (ObjectQuery<ClientContract>)
(from m in _cmsDb.Matters where m.CLIENT_CODE == clientCode && m.MATTER_CODE == matterCode
from mc in m.MatterContacts
select mc.ClientContact);
var data = query.Include("Name").ToList();
Upvotes: 1