【问题标题】:How is join+into clause converted to GroupJoinjoin+into 子句如何转换为 GroupJoin
【发布时间】:2019-11-08 16:39:50
【问题描述】:

如何编写代码:

var list = from uint x in M join uint y in N on x equals y into templist
           from uint z in templist join uint t in R on z equals t select z;

JoinGroupJoin 方法而言?

根据MS Docsjoininto 的组合转换为对GroupJoin 的调用。我只想知道上面的代码是如何调用GroupJoin 的。

【问题讨论】:

    标签: c# linq join


    【解决方案1】:

    这是我的手译,保留你的范围变量和类型信息:

    var list = M.GroupJoin(N, (uint x) => x, (uint y) => y, (uint x, IEnumerable<uint> templist) => templist)
                .SelectMany(templist => templist.Join(R, z => z, t => t, (z, t) => z));
    

    使用 LINQPad,您可以对 IQueryable 进行查询并返回 lambda 转换。

    把它放在 LINQPad 中:

    var M = Enumerable.Empty<uint>().AsQueryable();
    var N = Enumerable.Empty<uint>().AsQueryable();
    var R = Enumerable.Empty<uint>().AsQueryable();
    
    var list = from uint x in M
               join uint y in N on x equals y into templist
               from uint z in templist
               join uint t in R on z equals t
               select z;
    
    list.Dump();
    

    然后在 lambda 选项卡上取回这个:

    System.Linq.EmptyPartition`1[System.UInt32]
       .Cast ()
       .GroupJoin (
          System.Linq.EmptyPartition`1[System.UInt32]
             .Cast (), 
          x => x, 
          y => y, 
          (x, templist) => 
             new  
             {
                x = x, 
                templist = templist
             }
       )
       .SelectMany (
          temp0 => temp0.templist.Cast (), 
          (temp0, z) => 
             new  
             {
                temp0 = temp0, 
                z = z
             }
       )
       .Join (
          System.Linq.EmptyPartition`1[System.UInt32]
             .Cast (), 
          temp1 => temp1.z, 
          t => t, 
          (temp1, t) => temp1.z
       )
    

    因此,编译器似乎更喜欢转换为SelectMany 并链接Join,而不是嵌套Join。编译器似乎也喜欢传递所有范围变量,而不是注意到例如xtemp0 不再需要,只需 z 可以传递到 Join

    我会使用我喜欢的范围变量命名来编写我的原件:

    var list = M.GroupJoin(N, m => m, n => n, (m, nj) => nj)
                .SelectMany(nj => nj.Join(R, n => n, r => r, (n, r) => n));
    

    我会像这样模拟编译器流畅的链接:

    var list = M.GroupJoin(N, m => n, n => n, (m, nj) => nj)
                .SelectMany(nj => nj)
                .Join(R, n => n, r => r, (n, r) => n);
    

    最后,鉴于结果,没有理由使用GroupJoin,所以我会这样做:

    var list = from x in M
               join y in N on x equals y
               join t in R on y equals t
               select y;
    

    或者在 lambda 语法中:

    var list = M.Join(N, m => m, n => n, (m, n) => n)
                .Join(R, n => n, r => r, (n, r) => n);
    

    【讨论】:

      猜你喜欢
      • 2018-01-27
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 2015-04-17
      相关资源
      最近更新 更多