[英]how do I write LINQ query to retrieve distinct records based on only specific properties?
I've an array of objects DataTestplans
from which I try to retrieve records for a particular DataID
and ProductID
using the LINQ query shown, my current query has Distinct()
which distiguishes on all 5 mentioned properties,how do I retrieve distinct records based on properties DataID
, TestPlanName
, TCIndexList
and ProductID
? 我有一个对象
DataTestplans
数组,我尝试使用所示的LINQ查询从其中检索特定DataID
和ProductID
记录,我当前的查询具有Distinct()
,它Distinct()
了所有提到的5个属性,如何根据以下内容检索不同的记录属性DataID
, TestPlanName
, TCIndexList
和ProductID
?
DataTestplans:- 数据测试计划:
[
{
"DataTestPlanID": 0,
"DataID": 19148,
"TestPlanName": "string",
"TCIndexList": "string",
"ProductID": 2033915
},
{
"DataTestPlanID": 0,
"DataID": 19148,
"TestPlanName": "string",
"TCIndexList": "string",
"ProductID": 2033915
},
{
"DataTestPlanID": 0,
"DataID": 19149,
"TestPlanName": "string",
"TCIndexList": "string",
"ProductID": -2642
}
]
LINQ LINQ
DataTestPlans_DataID_ProductID = DataTestPlans.Where(c => c.DataID == DataID_ProductID_Record.DataID && c.ProductID == DataID_ProductID_Record.ProductID).Distinct();
You could do like this.. 你可以这样
DataTestPlans.Where(c => c.DataID == YourInput && c.ProductID == YourInput)
.GroupBy(x => new {x.DataID,x.TestPlanName,x.TCIndexList,x.ProductID})
.Select(x => x.First());
There are two ways to do, both highlighted in this question , no need for IComparer. 有两种方法可以完成此问题 , 这两种方法都不需要IComparer。 Here is a quick example you can play with (I did not use your actual object, because it's easier to explain this way):
这是一个可以使用的快速示例(我没有使用您的实际对象,因为这样更容易解释):
class Program
{
static void Main(string[] args)
{
var persons = Setup();
//option 1, can stream, option suggested by Jon Skeet
//https://stackoverflow.com/a/1300116/897326
var result1 = persons.
DistinctBy(m => new {m.FirstName, m.LastName});
//option 2, cannot stream, but does reference to DistinctBy
//https://stackoverflow.com/a/4158364/897326
var result2 = persons.
GroupBy(m => new { m.FirstName, m.LastName }).
Select(group => group.First());
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
private static List<Person> Setup()
{
var p1 = new Person
{
FirstName = "John",
LastName = "Doe",
Address = "USA"
};
var p2 = new Person
{
FirstName = "John",
LastName = "Doe",
Address = "Canada"
};
var p3 = new Person
{
FirstName = "Jane",
LastName = "Doe",
Address = "Australia"
};
var persons = new List<Person>();
persons.Add(p1);
persons.Add(p2);
persons.Add(p3);
return persons;
}
}
public static class LinqExtensions
{
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> knownKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (knownKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
}
You would have to use GroupBy()
, which will create an IEnumerable<IGrouping<TKey, TElement>>
which you can iterate over. 您将必须使用
GroupBy()
,这将创建一个IEnumerable<IGrouping<TKey, TElement>>
,您可以对其进行迭代。 You can access records either with group.First() or by some sort of aggregate function over the group. 您可以使用group.First()或通过组上的某种聚合函数来访问记录。
You can use multiple chained wheres . 您可以使用多个链接的wheres。 Make sure you it is IQueryable if you are making db call.
如果要进行数据库调用,请确保它是IQueryable。 An example is below
下面是一个例子
List<SomeClass> c = new List<SomeClass>();
var result = c.Where(x => x.ID == 4).Distinct().Where(y => y.Name == "foo").Distinct();
You can implement IEqualityComparer
and use that instead default in Distinct()
method. 您可以实现
IEqualityComparer
并在Distinct()
方法中使用默认值。 If you example implement DataTestPlansComparer
you can use like in following example: 如果您示例实现
DataTestPlansComparer
,则可以在以下示例中使用:
DataTestPlans_DataID_ProductID = DataTestPlans.Where(c => c.DataID == DataID_ProductID_Record.DataID && c.ProductID == DataID_ProductID_Record.ProductID).Distinct(new DataTestPlansComparer());
Note, your custom comparer should be passed as parameter to Distinct()
method. 注意,您的自定义比较器应作为参数传递给
Distinct()
方法。
In your case can be: 您的情况可以是:
public class DataTestPlanComparer : IEqualityComparer<DataTestPlan>
{
public bool Equals(DataTestPlan x, DataTestPlan y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.DataID == y.DataID && x.ProductID == y.ProductID;
}
public int GetHashCode(DataTestPlan dataTestPlan)
{
if (Object.ReferenceEquals(dataTestPlan, null)) return 0;
int hashDataTestPlanDataID = dataTestPlan.DataID == null ? 0 : dataTestPlan.DataID.GetHashCode();
int hashDataTestPlanProductID = dataTestPlan.ProductID.GetHashCode();
return hashDataTestPlanDataID ^ hashDataTestPlanProductID;
}
}
Please follow MSDN guide to implement IEqualityComparer. 请按照MSDN指南实施IEqualityComparer。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.