繁体   English   中英

LINQ左联接+默认为空+匿名类型+分组依据

[英]LINQ left join + default if empty + anonymous type + group by

我想知道给定问题的最佳解决方案是什么,这里简化:

  1. 我有两个本地存储的sql表,我想使用Default如果为Empty属性进行联接(左联接),则需要对这些数据进行分组

  2. 我不想在访问obj.column之前检查(obj == null),如果对于给定的行连接不成功,将会抛出错误

数据

LeftTable    RightTable    OUTPUT
 A B C        A B Z         A  B  C  Z
 1 1 1        1 1 5         1  1  1  5
 1 2 2        1 2 6         1  2  2  6
 5 6 7                      5  6  7 null

var RightTable = from row in Source
                 where row.X > 10
                 select new {        // anonymous type that I want to keep
                    A = row.AAA,
                    B = row.BBB,
                    Z = row.ZZZ
                 };

var test = from left in LeftTable
           from right in RightTable
             .Where(right => right.A == left.A
                && right.B == left.B )
             .DefaultIfEmpty( /* XXXXX */ )   //<-- this line is interesting
           group left by new {
             left.A
             left.B
             left.C
             right.Z  //<-- this will throw null exception error
           } into g     //  but I don't want to change it to 
           select g;    //  Z = (right != null) ? right.Z : (string) null

题:

我可以使用从代码中动态获得的任何内容填充DefaultIfEmpty中的参数吗?

我知道我可以创建如下的帮助程序类型,并替换RightTable select中的匿名类型,如果为空,则在默认值内使用它:

DefaultIfEmpty(new Helper())

但我不想这样做,因为我必须在现实生活中处理20,30+列。

public class Helper {
    public string A,
    public string B,
    public string C
}

如果您阅读到这里,非常感谢您的时间。 希望在这里得到一些解决方案。 谢谢。

我认为code说明了一切:

var LeftTable = new[]
        {
            new { A = 1, B=1, C=1 },
            new { A = 1, B=2, C=2 },
            new { A = 5, B=6, C=7 }
        }
        .ToList();


        var RightTable = new[]
        {
            new { A = 1, B=1, Z=5 },
            new { A = 1, B=2, Z=6 }
        }
        .ToList();


        var query = (from left in LeftTable
                     join right in RightTable
                        on new { left.A, left.B } equals new { right.A, right.B }
                        into JoinedList
                     from right in JoinedList.DefaultIfEmpty(new { A = 0, B = 0, Z = 0 })
                     group left by new
                     {
                         left.A,
                         left.B,
                         left.C,
                         right.Z
                     } into g
                     select g)
                    .ToList();

我遇到了与您相同的问题,必须找到一种方法,得出这样的结果(非常简化的示例):

var toReturn = from left in bd.leftys
               join rights in myAnonimousGroupedList on left.Id equals rights.leftId into joinings
               from right in joinings.DefaultIfEmpty()
               select new {
                   left.A
                   left.B
                   left.C
                   // Z = right != null ? right.Z : 0
                   Z = joinings.Any() ? right.Z : 0 // see what i did here?
               };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM