Ok so here is a quick version of my tables.
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;}
}
What I want is a query that will return all the Lines
including child collections and their child collections etc based on whether SchedItem.SchedDate
falls within a date range.
I tried the following in 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);
This seems wrong to me as the returned data is including all SchedItems
not just the ones based on the query.
UPDATE 1: Yeah I think I have my understanding wrong. I have set the following on my context configuration
db.Configuration.LazyLoadingEnabled = false;
db.Configuration.ProxyCreationEnabled = false;
When I run the code again I get a list of 33 Line
items with no child items. There should only be 1 'Line' item with many child items.
I changed my query to this and I now get the child items but the Line
count is still 33 which is wrong.
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)));
Try this
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
)
);
});
});
Your code make cartesian product because of couple from
statements. I'll skip configuration of DbContext and assume that you have enabled lazy loading. Try this:
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;
Another way to accomplish your goal is to add parrent to: SchedItem, Task, Tool, find SchedItems that meet your requirements and navigate through parents to Line. For more information go here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.