我有这个实体结构:
分类-> 有许多"团体"——> 有许多"类型"——> 有许多"物品"
我需要得到降序树(包含)通过Item过滤。Color == "blue",即:
var tree = from c in db.Categories
.Include(ct =>
ct.Groups
.Select(gr =>
gr.Types
.Select(pr => pr.Products)
)
)
join g in db.Groups on c.CategoryId equals g.CategoryId
join t in db.Types on g.GroupId equals t.GroupId
join i in db.Items on t.TypeId equals i.TypeId
where i.Color == "blue" // example filter
select c;
对于这个查询,我有降序树,但是我得到了其他颜色的item。
我只需要降序树的蓝色项目。
谢谢!
我假设你使用的是EntityFramework
你所需要做的就是一直包含,然后在你的实体上使用。any谓词。例如
var tree = db.Categories.Include(ct => ct.Groups.Select(gr =>
gr.Types.Select(pr =>
pr.Products)))
.Where(c => c.Groups.Any(g =>
g.Types.Any(t =>
t.Items.Any(i =>
i.Color == "blue"))))
.ToList()
一个警告,如果一个类型有多个项目,只有一个是蓝色的,你将得到它的所有项目,而不仅仅是蓝色的。但是,如果一个类型没有蓝色的项目,你将无法得到它。
如果你想在每一层过滤,你需要在每一层做投影。
编辑
如果你想过滤,你有两个选项:
- 每层投影
- 首先获得所有蓝色项目,然后检索他们的类型,组和类别。
1。每层投影
var tree = db.Categories.Include(ct => ct.Groups.Select(gr =>
gr.Types.Select(pr =>
pr.Products)))
.Where(c => c.Groups.Any(g =>
g.Types.Any(t =>
t.Items.Any(i =>
i.Color == "blue"))))
.Select(c => new { Groups = c.Groups.Where(g =>
g.Types.Any(t =>
t.Items.Any(i =>
i.Color == "blue"))
.Select( g => new { Types = g.Types.Where(t =>
t.Items.Any(i =>
i.Color == "blue"))
.Select(t => new { Items = t.Items.Where(i =>
i.Color == "blue")
.ToList() // Return list of anonymous types (
您不能投影回实体类型,您必须首先检索匿名类型,然后使用Linq2Objects投影到实体类型,因为EF将不允许您这样做。通常我所做的是直接投影到一个视图模型准备显示。