Entity Framework 4: готовая загрузка (включение) с фильтрами, использующими самопроверяющиеся объекты - PullRequest
8 голосов
/ 29 августа 2010

У меня есть решение, в котором я создал объекты самообследования, используя шаблоны RTM. Я разделил сущности и контекст между двумя проектами, чтобы я мог повторно использовать определения типов, поскольку планирую запустить клиент / сервер через WCF.

Один из моих методов обслуживания требуется для возврата графа объектов «Product» с дочерними объектами «ProductSku», которые в свою очередь имеют дочерние объекты «ProductPrice». Критерии выбора будут указаны в свойстве «Имя» объекта «Продукт» и в свойстве «FinancialPeriodID» объекта «ProductPriceObject». Пока я не включаю имя в поиск, но у меня возникают проблемы с возвратом графика.

Если я просто выполню следующий запрос (обратите внимание, этот синтаксис взят из LinqPad, а не из реального кода приложения) ...

from product in Products.Include("Skus.PriceHistory")
select product

... тогда я могу получить полный граф объектов для элементов, которые мне требуются, конечно, на данный момент нет фильтра.

Если вместо этого я введу фильтр следующим образом ...

from product in Products.Include("Skus.PriceHistory")
join sku in ProductSkus on product.ID equals sku.ProductID
join price in ProductPrices on sku.ID equals price.ProductSkuID
where price.FinancialPeriodID == 244
select product

... я ожидаю получить обратно объекты "Product", дочерние объекты "ProductSku" (которые находятся в коллекции "Skus" "Product") и их объекты "ProductPrice" (которые в коллекции «PriceHistory» («ProductSku») - но я получаю только объекты «Product», коллекция «Skus» пуста.

Я также пытался кодировать запрос как ...

from product in Products.Include("Skus.PriceHistory")
from sku in product.Skus
from price in sku.PriceHistory
where price.FinancialPeriodID == 244
select product

... но это тоже не имеет значения.

Очевидно, я должен что-то делать не так. Кто-нибудь может пролить свет на то, что это за нечто такое, как я уже несколько часов ходил кругами!

Ответы [ 4 ]

1 голос
/ 31 августа 2010

Может быть, проекция может сделать этот трюк?

Взгляните на коллекцию фильтров Linq с EF

1 голос
/ 29 августа 2010

Редактировать:

Как насчет:

from product in Products.Include("Skus.PriceHistory")
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244))
select product

Include уже выполняет все необходимые задачи для заполнения свойств навигации, поэтому дополнительные объединения для условий не требуются.Что еще более важно, любое ручное соединение или проекция изменит форму запроса, и Include не будет использоваться.

Также следует помнить, что при условии, что условие фильтрует только продукты.Он не будет фильтровать данные, загруженные с помощью Включить - вы получите все продукты с хотя бы одним sku, имеющим историю цен с идентификатором финансового периода 244, но эти продукты будут иметь все загруженные skus и истории цен.EF в настоящее время не поддерживает фильтрацию по include.Если вам также нужны отфильтрованные отношения, вы должны выполнить отдельные запросы для их получения.

0 голосов
/ 01 марта 2018

Наличие «Включить» не является гарантией загруженности, и его можно игнорировать по следующей причине. Это лучше объяснено в этой теме. Вы можете вручную выбрать таблицу, которую хотите загрузить, например,

var result = from product in Products.Include("Skus.PriceHistory")
from sku in product.Skus
from price in sku.PriceHistory
where price.FinancialPeriodID == 244
select new { p=product, pricehistory = product.Skus.PriceHistory};
var products = results.select(pph => pph.product);

https://social.msdn.microsoft.com/Forums/en-US/76bf1f22-7674-4e1e-85d3-68d29404e8db/include-is-ignored-in-a-subquery?forum=adodotnetentityframework

  • Включить относится только к элементам в результатах запроса: объектам, которые проецируется на крайнюю операцию в запросе.
  • Тип результатов должен быть типом сущности.
  • Запрос не может содержать операции, которые изменяют тип результат между Include и самой внешней операцией (то есть GroupBy () или операция Select (), которая изменяет тип результата)
  • Параметр, используемый параметром Include, представляет собой разделенный точками путь навигации. свойства, которые должны быть доступны для навигации из экземпляра типа возвращается при самой внешней операции
0 голосов
/ 01 сентября 2010

Самостоятельно отслеживаемые объекты не могут выполнять отложенную загрузку.Вот почему коллекция не пуста с генерацией сущности по умолчанию и не с STE.На самом деле ваш Включить никогда не загружает связанные объекты, если вы используете их в запросе.Теперь ваш L2E-запрос некорректен.Я думаю, что вы хотите сделать что-то вроде этого:

from p in 
   (from product in Products
    select new 
    { 
       Product = product, 
       Skus = 
          from sku in product.Skus
          select new 
          { 
             Sku = sku, 
             Prices = 
                from price in sku.Prices
                where price.FinancialPeriodID == 244            
                select price
          }
    }).AsEnumerable()
select p.Product;

Надеюсь, что поможет

Матье

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...