Ожидается, что ObjectQuery (Of T) .Include Entity Framework будет вести себя по-разному - PullRequest
0 голосов
/ 09 февраля 2012

Я не совсем понимаю, почему предложение Включить в этом запросе

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;

и последующие ссылки на свойства навигации, сделанные на результирующих объектах ClientContact, не удовлетворяются одним вызовом SQL. У сущности Matter есть множество MatterContact , и каждая из этих ссылок ссылается на один ClientContact , и у этого последнего объекта есть свойство навигации, которое называется Name который ссылается на имя сущность.

При трассировке SQL я вижу, что мое предложение Include вызвало объединение до самой таблицы, содержащей сущность Name . Вот извлечение соединений, которые я вижу:

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]

Итак, я вижу, что соединения происходят по всей иерархии. Однако когда я обращаюсь к свойствам сущности Name (например, .Name.FirstName), я вижу дополнительные вызовы SQL для поиска имени.

* * 1 022, например,
...
FROM (SELECT ...      FROM [dbo].[HBM_NAME] AS [HBM_NAME]) AS [Extent1]
WHERE [Extent1].[NAME_UNO] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=204629

Я бы подумал, что объект «Включить» перенесет сущность «Имя» в память для возвращенных объектов ClientContact. Но след будет указывать иначе.

1 Ответ

1 голос
/ 09 февраля 2012

Общее правило Include состоит в том, что оно работает, только если вы не используете проекцию или пользовательское соединение. Я думаю, что настоящее правило таково: форма запроса не должна меняться. Если вы используете Include на Matter Я ожидаю, что вы также должны вернуть Matter экземпляров, чтобы магия сделала свою работу. Вы используете Include на Matter, но выбираете ClientContract - форма запроса изменилась.

Что произойдет, если вы попробуете это:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...