2015-08-13 136 views
2

我有一個需求,我需要在2列中獲取具有相同組合的唯一記錄。 我的數據將是如Ca(列A)和CB(B欄)與一些數據Linq不同基於兩列

CACB
12
12
34
56
21
16
16
51

比方說,我需要與這兩者應該是唯一的列值1獲取記錄。

所以,我的最終結果應該是這樣的:

12
16
51

在這裏,我不應該得到記錄21因爲該組合已經存在了12在第一個記錄中。

下面是我試一下查詢:

var recentchats = (from s in MessagesCollection.AsQueryable() 
        where ([email protected] == mytopic || s.to == mytopic) 
        orderby s._id descending 
        select s).DistinctBy(x => x.from).Take(10).ToList(); 

我用moreLinq擴展DistinctBy,因爲我需要全程實錄(對不起,壞的格式和英語!!!)

在這裏,我的實際需求是獲取用戶最近的聊天

回答

0

所以你需要一種方法來檢測重複多列,順序無關緊要?你可以使用這個類:

public class MultiFieldIgnoreOrderComparer : IEquatable<IEnumerable<object>>, IEqualityComparer<IEnumerable<object>> 
{ 
    private IEnumerable<object> objects; 

    public MultiFieldIgnoreOrderComparer(IEnumerable<object> objects) 
    { 
     this.objects = objects; 
    } 

    public bool Equals(IEnumerable<object> x, IEnumerable<object> y) 
    { 
     return x.All(y.Contains); 
    } 

    public int GetHashCode(IEnumerable<object> objects) 
    { 
     unchecked 
     { 
      int detailHash = 0; 
      unchecked 
      { 
       // order doesn't matter, so we need to order: 
       foreach (object obj in objects.OrderBy(x => x)) 
        detailHash = 17 * detailHash + (obj == null ? 0 : obj.GetHashCode()); 
      } 
      return detailHash; 
     } 
    } 

    public override int GetHashCode() 
    { 
     return GetHashCode(this.objects); 
    } 

    public override bool Equals(object obj) 
    { 
     MultiFieldIgnoreOrderComparer other = obj as MultiFieldIgnoreOrderComparer; 
     if (other == null) return false; 
     return this.Equals(this.objects, other.objects); 
    } 

    public bool Equals(IEnumerable<object> other) 
    { 
     return this.Equals(this.objects, other); 
    } 
} 

你可以這樣使用它:

var recentchats = MessagesCollection.AsQueryable() 
    .Where(x => x.CA == 1 || x.CB == 1) 
    .GroupBy(x => new MultiFieldIgnoreOrderComparer(new[] { x.CA, x.CB })) 
    .Select(g => g.First()) 
    .ToList(); 
1

由於where已經確信這兩個值中的一個是永遠不變的,你可以使用的總和在distinctBy。 (例如1 + 2等於2 + 1)

DistinctBy(x => x.from + x.to) 

沒有在那裏,你可以使用最小值和最大值來仍然獲得獨特的對。

DistinctBy(x => new { Min=Math.Min(x.from, x.to), Max=Math.Max(x.from, x.to) })