2010-07-28 3 views
1

Я пытаюсь фильтровать вниз результаты, возвращаемые EF в только те, которые касаются - в приведенном ниже примере для тех, кто в течение года (formattedYear) и OrderType (filtOrder)Фильтрация график структуры сущностей объектов

I есть простой набор объектов

ЛЮДИ 1-М ЗАКАЗЫ 1-M OrderLines

с этими отношениями, которые уже определены в Model.edmx

в SQL я бы сделать что-то вроде ...

выберите * от людей внутренних присоединиться к ЗАКАЗЫ на ORDERS.PEOPLE_RECNO = PEOPLE.RECORD_NUMBER внутреннее соединение OrderLine на ORDERLINE.ORDER_RECNO = ORDERS.RECORD_NUMBER где [email protected] и [email protected]

Я попробовал несколько подходов ...

 var y = _entities.PEOPLE.Include("ORDERS").Where("it.ORDERS.ORDER_KEY=" + filtOrder.ToString()).Include("ORDERLINEs").Where("it.ORDERS.ORDERLINEs.SERVICE_YEAR='" + formattedYear + "'"); 

     var x = (from hp in _entities.PEOPLE 
       join ho in _entities.ORDERS on hp.RECORD_NUMBER equals ho.PEOPLE_RECNO 
       join ol in _entities.ORDERLINEs on ho.RECORD_NUMBER equals ol.ORDERS_RECNO 
       where (formattedYear == ol.SERVICE_YEAR) && (ho.ORDER_KEY==filtOrder) 
       select hp 
       ); 

у терпит неудачу с ORDER_KEY не является членом transient.collection ... и х возвращает правильные люди, но они все свои заказы прилагается - не только те, кого я буду.

Наверное, я пропустил что-то простое?

ответ

3

Представьте, что у вас есть человек с 100 заказами. Теперь вы отфильтровываете эти заказы до 10. Наконец, вы выбираете человека, у которого есть эти заказы. Угадай, что? У человека все еще есть 100 заказов!

То, о чем вы просите, не является сущностью, потому что вам не нужна вся сущность. То, что вам кажется нужным, - это подмножество данных от объекта. Поэтому выполните проект, который:

var x = from hp in _entities.PEOPLE 
     let ho = hp.ORDERS.Where(o => o.ORDER_KEY == filtOrder 
             && o.ORDERLINES.Any(ol => ol.SERVICE_YEAR == formattedYear)) 
     where ho.Any() 
     select new 
     { 
      Id = hp.ID, 
      Name = hp.Name, // etc. 
      Orders = from o in ho 
        select new { // whatever 
     }; 
+0

Это кажется приятным, но если вам нужно использовать результат в другом методе (представьте, что это сделано в DAL), использование анонимных объектов может быть проблемой ... Невозможно ли вернуть объект People? Потеряли бы фильтр, примененный к Заказу? –

+0

Крейг - да, я понимаю, но хочу избежать анонимных объектов именно по той причине, о которых упоминает Жюльен. Я просто хочу, чтобы мой репозиторий мог возвращать людей с нужными данными и передавать их строго типизированным представлениям, которые в других обстоятельствах могут работать со всем набором данных. – Andiih

+3

Вы можете вернуть POCOs вместо анонимных типов, если хотите (просто вставьте имя типа между 'new' и' {'). Однако вы не можете возвращать типы сущностей, поскольку EF не разрешает частично построенные объекты. –

1

Я не совсем уверен, что ваш вопрос, но следующее может быть полезно.

В инфраструктуре сущности, если вы хотите загрузить граф объектов и фильтровать дочерние элементы, вы можете сначала выполнить запрос для дочерних объектов и перечислить его (т. Е. Вызвать ToList()), чтобы childern был извлечен в памяти.

И тогда, когда вы извлекаете родительские объекты (и не используете .include), инфраструктура enitity сможет самостоятельно построить график (но обратите внимание, что вам может потребоваться сначала отключить ленивую загрузку, или загрузка займет много времени) , вот пример (если ваш контекст является «БД»):

db.ContextOptions.LazyLoadingEnabled = false; 

var childQuery = (from o in db.orders.Take(10) select o).ToList(); 

var q = (from p in db.people select p).ToList(); 


Теперь вы увидите, что каждый народ объект имеет десять порядка объекты


EDIT: Я был в торопитесь, когда я написал образец кода, и поэтому я еще не тестировал его, и я, вероятно, ошибся, заявив, что .Take (10) вернет десять заказов для каждого объекта, вместо этого я считаю, что .Take (10) вернет только десять общих заказов, когда ленивая загрузка отключается d, (и для случая, когда включена ленивая загрузка, я должен фактически проверить, каков будет результат), и для того, чтобы вернуть десять заказов для каждого объекта людей, вам может потребоваться более обширная фильтрация.

Но идея проста: сначала вы получаете все дочерние объекты и сущность Framework строит график самостоятельно.

+0

Я спустился по маршруту POCO некоторое время назад, но это интересный побочный эффект отключенной ленивой загрузки, ToList и дочерних запросов: я буду помнить об этом в будущем. – Andiih

+0

Он работает независимо от того, включена или отключена ленивая загрузка, но точка, которую я пытался сделать при упоминании ленивой загрузки, заключается в том, что хотя теория, почему это работает, заключается в том, что дети должны быть в памяти, когда родитель загружается все еще ленивая загрузка, и это также требует тщательных размышлений о том, какой результат будет при ленивой загрузке. –

Смежные вопросы