繁体   English   中英

如何编写LINQ查询以仅基于特定属性检索不同的记录?

[英]how do I write LINQ query to retrieve distinct records based on only specific properties?

我有一个对象DataTestplans数组,我尝试使用所示的LINQ查询从其中检索特定DataIDProductID记录,我当前的查询具有Distinct() ,它Distinct()了所有提到的5个属性,如何根据以下内容检索不同的记录属性DataIDTestPlanNameTCIndexListProductID

数据测试计划:

[
    {
    "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

            DataTestPlans_DataID_ProductID = DataTestPlans.Where(c => c.DataID == DataID_ProductID_Record.DataID && c.ProductID == DataID_ProductID_Record.ProductID).Distinct();

你可以这样

DataTestPlans.Where(c => c.DataID == YourInput && c.ProductID == YourInput)
             .GroupBy(x => new {x.DataID,x.TestPlanName,x.TCIndexList,x.ProductID})
             .Select(x => x.First());

有两种方法可以完成此问题两种方法都不需要IComparer。 这是一个可以使用的快速示例(我没有使用您的实际对象,因为这样更容易解释):

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;
            }
        }
    }
}

您将必须使用GroupBy() ,这将创建一个IEnumerable<IGrouping<TKey, TElement>> ,您可以对其进行迭代。 您可以使用group.First()或通过组上的某种聚合函数来访问记录。

您可以使用多个链接的wheres。 如果要进行数据库调用,请确保它是IQueryable。 下面是一个例子

List<SomeClass> c = new List<SomeClass>();
 var result = c.Where(x => x.ID == 4).Distinct().Where(y => y.Name == "foo").Distinct();

您可以实现IEqualityComparer并在Distinct()方法中使用默认值。 如果您示例实现DataTestPlansComparer ,则可以在以下示例中使用:

DataTestPlans_DataID_ProductID = DataTestPlans.Where(c => c.DataID == DataID_ProductID_Record.DataID && c.ProductID == DataID_ProductID_Record.ProductID).Distinct(new DataTestPlansComparer());

注意,您的自定义比较器应作为参数传递给Distinct()方法。

您的情况可以是:

        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;
            }
        }

请按照MSDN指南实施IEqualityComparer。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM