2016-07-22 2 views
0

Итак, вот краткая версия моих таблиц.Получить родительский объект на основе критериев дочернего критерия и включить

public class Line 
{ 
    // Bunch Of properties 
    // ... 
    public List<Tool> Tools {get;set;} 
} 

public class Tool 
{ 
    // Bunch Of properties 
    // ... 
    public List<Task> Tasks {get;set;} 
} 

public class Task 
{ 
    // Bunch Of properties 
    // ... 
    public List<SchedItem> SchedItems {get;set;} 
} 

public class SchedItem 
{ 
    public DateTime SchedDate {get;set;} 
} 

То, что я хочу, это запрос, который будет возвращать все Lines, включая дочерние коллекции и их дочерние коллекции и т.д., основанные на, попадет ли SchedItem.SchedDate в диапазоне дат.

Я попробовал следующее в LinqPad.

var line = (from p in Lines.Include(x => x.Tools.Select(m => m.Tasks.Select(s => s.SchedItems))) 
         from t in p.Tools 
         from m in t.Tasks 
         from s in m.SchedItems 
         where s.SchedDate >= StartDateQuery && 
           s.SchedDate <= EndDateQuery 
         select p); 

Это кажется мне неправильным, как возвращаемые данные, включая все SchedItems не только те, на основании запроса.

ОБНОВЛЕНИЕ 1: Да, я думаю, что у меня есть мое понимание неправильно. Я поставил следующее на моей конфигурации контекста

db.Configuration.LazyLoadingEnabled = false; 
db.Configuration.ProxyCreationEnabled = false; 

Когда я запускаю код еще раз я получаю список из 33 Line пунктов, не имеющих дочерних элементов. Должен быть только 1 элемент «Линия» со многими дочерними элементами.

Я изменил свой запрос на это, и теперь я получаю дочерние элементы, но счет Line по-прежнему 33, что является неправильным.

var line = (from p in Lines 
         from t in p.Tools 
         from m in t.Tasks 
         from s in m.SchedItems 
         where s.SchedDate >= StartDateQuery && 
           s.SchedDate <= EndDateQuery 
         select p).Include(x => x.Tools.Select(m => m.Tasks.Select(s => s.SchedItems))); 
+1

Я думаю, что это было задано много раз. Яркие загрузочные нагрузки ** сущности **. Это все или ничего. например при загрузке «Task.ShedItems» содержит все элементы, потому что это имеет место с точки зрения ** entity **. Если вы хотите применить фильтрацию, то вы должны использовать проекцию, а не 'Include' (которая игнорируется в таких сценариях). –

+0

Ну ладно, спасибо за это, я посмотрю на это. – Gaz83

ответ

1

Попробуйте

var lines = Lines.Where(i => 
       i.Tools.Any(t => 
          t.Tasks.Any(y => 
            y.SchedItems.Any(u => 
               u.SchedDate >= StartDateQuery && 
               s.SchedDate <= EndDateQuery 
               ) 
             ) 
           ) 
       ); 

lines.ForEach(i => new 
       { 
        i.Tools = i.Tools.Where(t => 
               t.Tasks.Any(y => 
                 y.SchedItems.Any(u => 
                    u.SchedDate >= StartDateQuery && 
                    s.SchedDate <= EndDateQuery 
                    ) 
                  ) 
             ); 
        i.Tools.ForEach(t => new 
        { 
         t.Tasks = t.Tasks.Where(y => 
                y.SchedItems.Any(u => 
                   u.SchedDate >= StartDateQuery && 
                   s.SchedDate <= EndDateQuery 
                   ) 
               ); 
        }); 
       } 
      ); 
+0

см. Мой ответ на @Kedrzu – Gaz83

+0

@ Gaz83 Ответ обновлен. – NEER

+0

@ Kedrzu просто попытался скопировать и вставить, и первая ошибка, которую я получил, была с 'lines.Foreach', поскольку визуальная студия заявляет, что не может решить' foreach' – Gaz83

1

Ваш код сделать декартово произведение из-за пары from заявлений. Я пропущу конфигурацию DbContext и предположим, что вы включили ленивую загрузку. Попробуйте это:

var line = from p in ls 
      where p.Tools 
       .Any(to=> to.Tasks 
        .Any(ta=> ta.SchedItems 
         .Any(s=> s.SchedDate >= StartDateQuery && s.SchedDate <= EndDateQuery))); 
      select p; 

Другой путь для достижения своей цели является добавление parrent к: SchedItem, задач, инструмент, найти SchedItems, которые отвечают вашим требованиям и провести через родителей линии. Для получения дополнительной информации перейдите here

+0

Просто попробовал это, и он решил проблему возврата правильного номера элементов 'Line'. Проблема, которую я все еще имею, заключается в том, что мне нужно, чтобы она включала соответствующие дочерние элементы. Кроме того, когда я разворачиваю дочерние элементы в LinqPad, я перехожу к 'SchedItems', и я вижу, что он включает все элементы, а не только те, которые основаны на' SchedDate'criteria – Gaz83

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