我有一个问题:(我通过映射表(3)在两个表(1和2)之间有很多表:
(1)Trees / (2)Insects
TreeID <- (3)TreeInsects -> InsectID
然后是一对多的关系:
Trees.ID -> Leaves.TreeID
我想执行一个查询,它将为我提供昆虫收集的所有叶子(通过树木 - 昆虫映射表)。
E.g。我有List<Insects>
,我希望所有通过树 - 昆虫映射表与列表中的任何昆虫相关联的叶子。
这似乎是一项简单的任务,但由于某种原因,我在执行此操作时遇到了麻烦!!
我拥有的最好:但Single()使其不正确:
from l in Leaves
where (from i in Insects
select i.ID)
.Contains((from ti in l.Tree.TreeInsects
select ti.InsectID).Single())
select l;
答案 0 :(得分:2)
(from i in insectsCollection
select from l in Leaves
let treeInsectIDs = l.Tree.TreeInsects.Select(ti => ti.InsectID)
where treeInsectIDs.Contains(i.ID)
select l)
.SelectMany(l => l)
.Distinct();
答案 1 :(得分:1)
我的SQL语法很糟糕所以我会写扩展名。
ctx.Leaves.Where(l => ctx.TreeInsects.Where( ti => list_with_insects.Select(lwi => lwi.InsectID).Contains( ti.InsectID ) ).Any( ti => ti.TreeID == l.TreeID ) );
答案 2 :(得分:0)
尝试调查SelectMany方法 - 我认为这可能是您需要的关键。
我会得到一个可用于该昆虫的树木列表,然后将SelectMany钉在最后,并拉出与该树相关的树叶集合。
答案 3 :(得分:0)
List<int> insectIds = localInsects.Select(i => i.ID).ToList();
//note - each leaf is evaluated, so no duplicates.
IQueryable<Leaf> query =
from leaf in myDataContext.Leaves
where leaf.Tree.TreeInsects.Any(ti => insectIds.Contains(ti.InsectId))
select leaf;
//note, each matching insect is found, then turned into a collection of leaves.
// if two insects have the same leaf, that leaf will be duplicated.
IQueryable<Leaf> query2 =
from insect in myDataContext.Insects
where insectIds.Contains(insect.ID)
from ti in insect.TreeInsects
from leaf in ti.Tree.Leaves
select leaf;
另请注意,Sql Server的参数限制为~2100。 LinqToSql将很乐意生成一个包含更多昆虫ID的查询,但是当您尝试运行它时,您将获得一个sql异常。要解决此问题,请在较小批次的ID上多次运行查询。
答案 4 :(得分:0)
你如何获得这份昆虫清单?这也是一个查询吗?
无论如何,如果你不介意性能(如果你有一个大数据库,SelectMany可能会很慢),这应该有效:
List<Insect> insects = .... ; //(your query/method)
IEnumerable<Leave> leaves = db.TreeInsects
.Where(p=> insects.Contains(p.Insect))
.Select(p=>p.Tree)
.SelectMany(p=>p.Leaves);