2012-09-26 53 views
4

我對LINQ相當陌生,而且我可能已將自己描繪在這裏的一個角落。我有兩個列表(左和右),我需要:基於特定字段獲取兩個列表之間的差異

一個)獲取基於某些領域

b)獲取左邊不匹配右側項目匹配的項目

ç)獲取左邊

的匹配與不匹配合適的項目,如果某些字段是相等的發現。其他字段可能包含也可能不包含值,但不得影響匹配比較。

要獲得項目一個我執行上都列出了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之外,還有其他的方式來獲得兩個列表之間的區別嗎?

回答

4

這使用IntersectExcept(與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()); 
+0

謝謝。我已經使用了你和Cuong Le的解決方案。我不知道有'Intersect',所以它會爲我節省'InnerJoin' – Devmonster

+0

不客氣,我很樂意提供幫助。 –

0

如何

一)

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}); 
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()); 
+0

謝謝你,雖然在你的代碼listA.Except(listA ...'我想你的意思是'listB'在第二個'listA'上。 – Devmonster

相關問題