Linq 左外部连接与自定义比较器
本文关键字:自定义 比较器 连接 外部 Linq | 更新日期: 2023-09-27 18:30:54
我正在尝试进行一个left outer join
查询,该查询也具有custom comparator
。
我有以下列表:
List<ColumnInformation> list1;
List<ColumnInformation> list2;
它们保存有关 SQL 列的信息(数据类型、名称、表等)。我已经覆盖了班级的Equals
,并做了一个operator ==
和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);
我的问题是:如何同时进行左外连接并使用比较器?
据我所知,查询语法没有比较器的关键字,扩展方法也没有into
关键字的任何内容。
我不在乎结果是在查询语法还是扩展方法中。
执行此操作的方法是使用GroupJoin
和SelectMany
(以平展结果):
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 }
);
您可以将子查询与 其中
: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
};