我对LINQ很新,我可能已经把自己画到了一个角落。我有两个列表(左和右),我需要:
a )根据特定字段获取匹配项
b )获取左侧没有匹配项目的项目
c )获取右侧没有匹配项目的项目
如果某些字段相等,则会找到匹配项。其他字段可能包含也可能不包含值,但不得影响匹配比较。
要获取 a 项,我在两个列表上都执行了JOIN
:
var q = from a in r1
from b in r2
where a.Prop1 == b.Prop1 && a.Prop3 == b.Prop3
select new { a.Prop1, a.Prop2, b.Prop3 };
我不确定从哪里开始。我认为我不能使用.Except()
,因为两个列表的其他属性会有所不同,可能导致比较中断。
我也尝试使用Left Join
并获取没有匹配的项目:
var q =
from c in r1
join p in r2 on c.Prop1 equals p.Prop1
into cp
from p in cp.DefaultIfEmpty()
select new { Prop1 = c.Prop1, Prop2 = p == null ? "N/A" : p.Prop2 };
然而我发现你无法比较多个字段来比较。
使用LINQ,Left Join
上有多个字段吗?
还有其他方法(除了LINQ)来区分两个列表吗?
答案 0 :(得分:4)
这使用Intersect
和Except
(类似于Cuong Le的解决方案):
public class MyComparer : IEqualityComparer<YourClass>
{
#region IEqualityComparer<YourClass> Members
public bool Equals(YourClass x, YourClass y)
{
return
x.Prop1.Equals(y.Prop1) && x.Prop3.Equals(y.Prop3);
}
public int GetHashCode(YourClass obj)
{
int hCode = obj.Prop1.GetHashCode() ^ obj.Prop3.GetHashCode();
return hCode.GetHashCode();
}
#endregion
}
// matched elements from both lists
var r1 = l1.Intersect<YourClass>(l2, new MyComparer());
// elements from l1 not in l2
var r2 = l1.Except<YourClass>(l2, new MyComparer());
// elements from l2 not in l1
var r3 = l2.Except<YourClass>(l1, new MyComparer());
答案 1 :(得分:2)
默认情况下,Except
方法使用EqualityComparer.Default,如果您拥有具有不同属性值的对象,则无法使用
但您可以使用其他重载方法Except来自定义EqualityComparer<T>
,假设它忽略Pro3
public class CustomComparer : EqualityComparer<A>
{
public override int GetHashCode(A a)
{
int hCode = a.Pro1.GetHashCode() ^ a.Pro2.GetHashCode();
return hCode.GetHashCode();
}
public override bool Equals(A a1, A a2)
{
return a1.Pro1.Equals(a2.Pro1) && a1.Pro2.Equals(a2.Pro2)
}
}
然后您可以使用Except
:
listA.Except(listB, new CustomComparer());
答案 2 :(得分:0)
怎么样
A)
r1.Where(x=>r2.Any(y=>x.Prop1==y.Prop1&&x.Prop3==y.Prop3))
.Select(x=>new { x.Prop1,x.Prop2,x.Prop3});
b)中
r1.Where(x=>!r2.Any(y=>x.Prop1==y.Prop1&&x.Prop3==y.Prop3))
.Select(x=>new { x.Prop1,x.Prop2,x.Prop3});
c)中
r2.Where(x=>!r1.Any(y=>x.Prop1==y.Prop1&&x.Prop3==y.Prop3))
.Select(x=>new { x.Prop1,x.Prop2,x.Prop3});