3

我有一个要求,我需要在 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

在这里我不应该得到记录21因为该组合已经存在于第一条记录中12

这是我尝试过的查询:

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,因为我需要整个记录。(抱歉格式和英文不好!!!)

在这里,我的实际需求是获取用户最近的聊天记录

4

2 回答 2

1

由于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) })
于 2015-08-13T13:29:55.973 回答
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();
于 2015-08-13T13:28:24.143 回答