LINQ查询与Distinct和Union

fre*_*hie 15 .net c# linq

我目前有2个查询返回MyModel列表,如下所示:

var q1 = ....
         select new MyModel()
         {
             TheData1 = ...
             TheData2 = ...
             TheUniqueID = ...
         }

var q2 = ....
         select new MyModel()
         {
             TheData1 = ...
             TheData2 = ...
             TheUniqueID = ...
         }
Run Code Online (Sandbox Code Playgroud)

如果在q1我有:

TheUniqueID = 2,3,6,9,11 
Run Code Online (Sandbox Code Playgroud)

在q2我有:

TheUniqueID = 2,4,7,9,12
Run Code Online (Sandbox Code Playgroud)

如何编写查询以便我获取MyModel的列表

TheUniqueID = 2,3,4,6,7,9,11,12
Run Code Online (Sandbox Code Playgroud)

换句话说,每个TheUniqueID只出现一次(即2和9不重复).

我开始关注Union并且很明显,但我想知道我是否需要2个语句.

欢迎任何建议.

Tho*_* Li 26

我认为frenchie想要一个MyModel回归列表,而不仅仅是TheUniqueID.

您需要创建一个MyModelTheUniqueIDComparer类并将其作为第二个参数的新实例传递到Union:

class MyModelTheUniqueIDComparer : IEqualityComparer<MyModel>
{
    public bool Equals(MyModel x, MyModel y)
    {
        return x.TheUniqueID == y.TheUniqueID;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(MyModel myModel)
    {
        return myModel.TheUniqueID.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话来得到结果:

var result = q1.Union(q2, new MyModelTheUniqueIDComparer());
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/bb358407.aspx.

更新:

试试这个:

public class A
{
    public string TheData1 { get; set; }
    public string TheData2 { get; set; }
    public string UniqueID { get; set; }
}

public class AComparer : IEqualityComparer<A>
{

    #region IEqualityComparer<A> Members

    public bool Equals(A x, A y)
    {
        return x.UniqueID == y.UniqueID;
    }

    public int GetHashCode(A obj)
    {
        return obj.UniqueID.GetHashCode();
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

并测试:

var listOfA = new List<A>();
var q1 = from a in listOfA
                 select new A()
             {
                 TheData1 = "TestData",
                 TheData2 = "TestData",
                 UniqueID = a.UniqueID
             };

var anotherListOfA = new List<A>();
var q2 = from a in anotherListOfA
                 select new A()
                 {
                     TheData1 = "TestData",
                     TheData2 = "TestData",
                     UniqueID = a.UniqueID
                 };

q1.Union(q2, new AComparer());
Run Code Online (Sandbox Code Playgroud)

确保你有 using System.Linq;


vla*_*lad 9

Union使用两个集合中的唯一值创建一个Enumerable.换句话说,你不需要Distinct.

编辑:这里的联盟的例子

edit2:忘记它不是UniqueIDs你连接的列表.我删除了建议的代码,因为它错了.Union如果你实现了一个IEqualityComparer,你应该可以做一个简单的事情,但这可能是过度的.


Bro*_*ass 6

正如所指出的,如果您将列表与.Union()组合,您将必须通过使用为您的类型传递IEqualityComparer的重载来定义唯一性。

var result = q1.Union(q2, myEqualityComparer);
Run Code Online (Sandbox Code Playgroud)

否则,您可以更轻松地DistinctBy( x=> x.TheUniqueId)MoreLinq项目中使用:

var result = q1.Concat(q2).DistinctBy(c => c.TheUniqueID);
Run Code Online (Sandbox Code Playgroud)