C# LINQ到SQL,其中集合包含集合

C# LINQ到SQL,其中集合包含集合,c#,sql-server-2008,linq-to-sql,C#,Sql Server 2008,Linq To Sql,我有一个问题:(通过映射表(3),我在两个表(1和2)之间有一个多个表): 我想执行一个查询,它将为我提供昆虫集合的所有叶子(通过树昆虫映射表) 例如,我有列表,我希望所有与列表中任何昆虫有关联的叶子都通过树昆虫映射表 这似乎是一个简单的任务,但出于某种原因,我做这件事有困难 我所拥有的最好的:但是Single()使它不正确: from l in Leaves where (from i in Insects select i.

我有一个问题:(通过映射表(3),我在两个表(1和2)之间有一个多个表):

我想执行一个查询,它将为我提供昆虫集合的所有叶子(通过树昆虫映射表)

例如,我有
列表
,我希望所有与列表中任何昆虫有关联的叶子都通过树昆虫映射表

这似乎是一个简单的任务,但出于某种原因,我做这件事有困难

我所拥有的最好的:但是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;
试着研究一下这个方法——我认为这可能是你需要的关键


我会得到一个可供昆虫使用的树的列表,然后将SelectMany固定到最后,并取出与该树相关的叶子集合。

我不擅长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 ) );
List instetids=localInsects.Select(i=>i.ID.ToList();
//注意-每个叶都经过计算,因此没有重复。
可查询查询=
从myDataContext.Leaves中的叶
其中leaf.Tree.TreeInsects.Any(ti=>instetids.Contains(ti.instetid))
选择叶片;
//注意,每一个匹配的昆虫都被找到,然后变成一堆叶子。
//如果两种昆虫有相同的叶子,那叶子将被复制。
可查询的查询2=
来自myDataContext中的昆虫。昆虫
其中昆虫包含(昆虫ID)
来自昆虫树的ti
从树上的叶子
选择叶片;

另外请注意,Sql Server的参数限制为~2100。LinqToSql很乐意生成一个包含更多昆虫ID的查询,但当您尝试运行它时,会出现Sql异常。要解决此问题,请在较小的ID批上多次运行查询。

如何获取昆虫列表?它也是一个查询吗

无论如何,如果您不介意性能(如果您有一个大数据库,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);
列出昆虫=..;//(您的查询/方法)
IEnumerable leaves=db.TreeInsects
.其中(p=>昆虫.包含(p.昆虫))
.Select(p=>p.Tree)
.SelectMany(p=>p.Leaves);

这是一个基于Leaves Sql Server表的Linq to Sql生成的类型。我的示例查询中的上下文将是Leaves表,其中的表达式包含一个无重载编译器表达式…有什么想法吗?谢谢,我标记了最早的正确答案。我对这一点和上面的答案进行了计时,它们的执行方式与w几乎相同根据我掌握的数据。谢谢!进一步分析,另一个是对这两种工作方法的快速查询,这很可能是真的。写这篇文章时,有点陶醉于对效率的思考:)太好了!对于我需要执行相同类型的查询,这一点非常有效。谢谢,我标记了您的,因为这是第一个答案,下面Grozz的查询语法也很有效,我对它们进行了计时,它们与我在数据库中的数据执行相同的操作。谢谢进一步分析,这是两种工作方法中更快的查询
ctx.Leaves.Where(l => ctx.TreeInsects.Where( ti => list_with_insects.Select(lwi => lwi.InsectID).Contains( ti.InsectID ) ).Any( ti => ti.TreeID == l.TreeID ) );
(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();
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;
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);