我有一个要求,我需要在2列中获取具有相同组合的唯一记录。我的数据就像CA(A列)和CB(B列),有一些数据
CA
CB
1
2
1
2
3
4
5
6
2
1
1
6
1
6
5
1
假设,我需要从两个列中获取值为1
的记录,这两个列应该是唯一的。
所以,我的最终结果应该是:
1
2
1
6
5
1
这里我不应该得到记录2
, 1
,因为在第一个记录中已经存在1
, 2
的组合。
这是我尝试过的查询:
var recentchats = (from s in MessagesCollection.AsQueryable()
where (s.@from == mytopic || s.to == mytopic)
orderby s._id descending
select s).DistinctBy(x => x.from).Take(10).ToList();
我使用moreLinq
扩展DistinctBy
,因为我需要整个记录。(抱歉格式和英文不好!!)
这里,我的实际需求是获取用户最近的聊天记录
由于where
已经确保两个值中的一个总是相同的,您可以使用distinctBy
中的总和。(例如1 + 2等于2 + 1)
DistinctBy(x => x.from + x.to)
没有where,您可以使用Min和Max来获得唯一对。
DistinctBy(x => new { Min=Math.Min(x.from, x.to), Max=Math.Max(x.from, x.to) })
所以您需要一种方法来检测重复根据多个列和顺序无关?你可以使用这个类:
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();