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

ここでは、最初のレコードに組み合わせが として既に存在するため、レコード を取得しないで2ください。112

私が試したクエリは次のとおりです。

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は 2 つの値のいずれかが常に同じであることを既に確認しているため、 で合計を使用できます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 に答える