Linq使用自定义比较器左外连接

时间:2013-09-11 16:06:31

标签: c# linq join

我正在尝试制作一个left outer join的{​​{1}}查询。

我有以下列表:

custom comparator

这些包含有关SQL列(数据类型,名称,表等)的信息。我已为该课程覆盖了List<ColumnInformation> list1; List<ColumnInformation> list2; ,并制作了Equalsoperator ==

我理解如何make a left outer join

operator !=

我了解如何制作和使用自定义var leftOuterJoin = from l1 in list1 join l2 in list2 on l1.objectID equals l2.objectID into temp from l2 in temp.DefaultIfEmpty(new { l1.ID, Name = default(string) }) select new { l1.ID, ColumnName1 = l1.Name, ColumnName2 = l2.Name, };

IEqualityComparer

我的问题是:如何同时执行左外连接并同时使用我的比较器

据我所知,查询语法没有比较器的关键字,扩展方法没有public class ColumnComparer : IEqualityComparer<ColumnInformation> { public bool Equals(ColumnInformation x, ColumnInformation y) { return x == y; //this uses my defined == operator } public int GetHashCode(ColumnInformation obj) { return 1; //forcing the join to use Equals, just trust me on this } } ColumnComparer cc = new ColumnComparer(); var joinedList = list1.Join(list2, x => x, y => y, (x, y) => new {x, y}, cc); 关键字的任何内容。

我不在乎结果是查询语法还是扩展方法。

2 个答案:

答案 0 :(得分:3)

您这样做的方法是使用GroupJoinSelectMany(以平展结果):

ColumnComparer cc = new ColumnComparer();
var joinedList = list1
    .GroupJoin(list2,
        x => x,
        y => y,
        (x, g) => new {x, g},
        cc)
    .SelectMany(
        z => z.g.DefaultIfEmpty(),
        (z, b) => new  { x = z.x, y = b } 
    );

答案 1 :(得分:0)

您可以将子查询与Where:

结合使用
var leftOuterJoin = from l1 in list1
                    select new 
                   {
                      jointList = (from l2 in list2 
                                   where l2.objectID == l1.ObjectID // <-- and you can do any other comparing logic in where clause
                                   select l2).DefaultIfEmpty(),                        
                      l1id = l1.ID,
                      ColumnName1 = l1.Name,
                      ColumnName2 = l2.Name
};