LEFT OUTER JOIN in LINQ

后端 未结 22 2507
臣服心动
臣服心动 2020-11-21 04:49

How to perform left outer join in C# LINQ to objects without using join-on-equals-into clauses? Is there any way to do that with where clause? Corr

22条回答
  •  遇见更好的自我
    2020-11-21 05:13

    This is the general form (as already provided in other answers)

    var c =
        from a in alpha
        join b in beta on b.field1 equals a.field1 into b_temp
        from b_value in b_temp.DefaultIfEmpty()
        select new { Alpha = a, Beta = b_value };
    

    However here's an explanation that I hope will clarify what this actually means!

    join b in beta on b.field1 equals a.field1 into b_temp
    

    essentially creates a separate result set b_temp that effectively includes null 'rows' for entries on the right hand side (entries in 'b').

    Then the next line:

    from b_value in b_temp.DefaultIfEmpty()
    

    ..iterates over that result set, setting the default null value for the 'row' on the right hand side, and setting the result of the right hand side row join to the value of 'b_value' (i.e. the value that's on the right hand side,if there's a matching record, or 'null' if there isn't).

    Now, if the right hand side is the result of a separate LINQ query, it will consist of anonymous types, which can only either be 'something' or 'null'. If it's an enumerable however (e.g. a List - where MyObjectB is a class with 2 fields), then it's possible to be specific about what default 'null' values are used for its properties:

    var c =
        from a in alpha
        join b in beta on b.field1 equals a.field1 into b_temp
        from b_value in b_temp.DefaultIfEmpty( new MyObjectB { Field1 = String.Empty, Field2 = (DateTime?) null })
        select new { Alpha = a, Beta_field1 = b_value.Field1, Beta_field2 = b_value.Field2 };
    

    This ensures that 'b' itself isn't null (but its properties can be null, using the default null values that you've specified), and this allows you to check properties of b_value without getting a null reference exception for b_value. Note that for a nullable DateTime, a type of (DateTime?) i.e. 'nullable DateTime' must be specified as the 'Type' of the null in the specification for the 'DefaultIfEmpty' (this will also apply to types that are not 'natively' nullable e.g double, float).

    You can perform multiple left outer joins by simply chaining the above syntax.

提交回复
热议问题