У меня есть решение, в котором я создал самотрекинг сущностей с использованием шаблонов 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
... но это не дает Разница тоже.
Очевидно, я должен делать что-то не так. Кто-нибудь может пролить свет на то, что это что-то, как я был в этом в течение нескольких часов, теперь ходить по кругу!
Может быть, на этот трюк способна проекция?
Взгляните на коллекцию фильтров Linq с EF
Редактировать:
Как насчет:
from product in Products.Include("Skus.PriceHistory")
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244))
select product
Include
уже выполняет все необходимые задачи для заполнения свойств навигации, поэтому дополнительные соединения для условия не нужны. Что еще более важно, любое ручное объединение или проекция изменит форму запроса, и Include
не будет использоваться.
Также имейте в виду, что условие фильтрует только товары. Он не будет фильтровать данные, загруженные с помощью Include — вы получите все продукты, по крайней мере, с одним артикулом, имеющим историю цен с идентификатором финансового периода 244, но для этих продуктов будут загружены все артикулы и истории цен. В настоящее время EF не поддерживает фильтрацию при включении. Если вам также нужны отфильтрованные отношения, вам нужно выполнить отдельные запросы, чтобы получить их.
Сущности с самостоятельным отслеживанием не могут выполнять отложенную загрузку. Вот почему коллекция не пуста при генерации сущностей по умолчанию, а не при STE. На самом деле ваш Include никогда не загружает связанные объекты, если вы используете их в запросе. Теперь ваш запрос 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;
Надеюсь, это поможет
Матье