LINQ查询与Distinct和Union

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

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

如果在q1我有:

 TheUniqueID = 2,3,6,9,11 

在q2我有:

 TheUniqueID = 2,4,7,9,12 

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

 TheUniqueID = 2,3,4,6,7,9,11,12 

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

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

欢迎任何建议。

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

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

 class MyModelTheUniqueIDComparer : IEqualityComparer { 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(); } } 

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

 var result = q1.Union(q2, new MyModelTheUniqueIDComparer()); 

有关详细信息,请参阅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 { #region IEqualityComparer Members public bool Equals(A x, A y) { return x.UniqueID == y.UniqueID; } public int GetHashCode(A obj) { return obj.UniqueID.GetHashCode(); } #endregion } 

并测试:

 var listOfA = new List(); var q1 = from a in listOfA select new A() { TheData1 = "TestData", TheData2 = "TestData", UniqueID = a.UniqueID }; var anotherListOfA = new List(); var q2 = from a in anotherListOfA select new A() { TheData1 = "TestData", TheData2 = "TestData", UniqueID = a.UniqueID }; q1.Union(q2, new AComparer()); 

确保您using System.Linq;

Union从两个集合中创建一个具有唯一值的Enumerable。 换句话说,你不需要Distinct

编辑: 这里的联盟的例子

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

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

 var result = q1.Union(q2, myEqualityComparer); 

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

 var result = q1.Concat(q2).DistinctBy(c => c.TheUniqueID); 

没有IEqualityComparerer的低效单行答案

使用MoreLinq源代码作为灵感,这将给出一个唯一的列表:

简短回答(OrderBy不是必需的,但如果没有使用,答案就是2,3,6,9,11,4,7,12):

 var concattedUniqueList = theUniqueIDList1.Concat(theUniqueIDList2) .GroupBy(f=>f.UniqueID, f=>f).Select(g => g.First()).OrderBy(f=>f.UniqueID); 

完整答案:

 //INPUT //theUniqueIDList1 = 2,3,6,9,11 //theUniqueIDList2 = 2,4,7,9,12 //OUTPUT //2,3,4,6,7,9,11,12 public class MyModel { public string TheData1 { get; set; } public string TheData2 { get; set; } public int UniqueID { get; set; } } public static void GroupByEx1() { // Create a list of Models. List theUniqueIDList1 = new List{ new MyModel { TheData1="Barley", UniqueID=2 }, new MyModel { TheData1="Boots", UniqueID=3 }, new MyModel { TheData1="Whiskers", UniqueID=6 }, new MyModel { TheData1="Daisy", UniqueID=9 }, new MyModel { TheData1="Preti", UniqueID=11 } }; List theUniqueIDList2 = new List{ new MyModel { TheData1="Barley", UniqueID=2 }, new MyModel { TheData1="Henry", UniqueID=4 }, new MyModel { TheData1="Walsh", UniqueID=7 }, new MyModel { TheData1="Daisy", UniqueID=9 }, new MyModel { TheData1="Ugly", UniqueID=12 } }; var concattedUniqueList = theUniqueIDList1.Concat(theUniqueIDList2) .OrderBy(f=>f.UniqueID).GroupBy(f=>f.UniqueID, f=>f).Select(g => g.First()); foreach (var item in concattedUniqueList) { Console.WriteLine("UniqueId: {0}({1})", item.UniqueID, item.TheData1); } } void Main() { GroupByEx1(); //2,3,4,6,7,9,11,12 } 

注意:与使用IEqualityComparer进行速度相比 – 对于IEqualityComparer,对于Concat 100 ns,每个698 ns为10000次

在LinqPad开发