繁体   English   中英

LINQ选择不同的集合并检索不同的列

[英]LINQ select distinct set and retrive different column

我希望能够执行以下查询:

select distinct studentname, subject, grade from studenttable;

学生表具有以下字段:

studentid
studentname
subject
grade

我现在使用的linq查询是:

var students=dc.Select(s => new {s.studentname, s.subject, s.grade}).Distinct();

dc是数据上下文。

该查询有效,但是如何在仍满足学生studentname, subject, grade设置的特殊条件的同时,获得学生id

这里的问题是,您已经收集了必要数据的三个属性,尽管这些属性足以通过Distinct传递,但没有任何链接返回其原始数据,并且任何此类链接都会破坏Distinct的默认实现。

但是,您可以做的是使用带有IEqualityComparer的distance的重载。 这将允许您在整个集合上运行Distinct时仅在所需字段上进行相等性比较。

var students = dc
    .AsEnumerable() // In case you're using a linq-to-sql framework, this will ensure the query execute in-memory
    .Distinct(new SpecialtyComparer());

//...

public class SpecialtyComparer : IEqualityComparer<StudentTable>
{
    public int GetHashCode(StudentTable s)
    {
        return s.studentname.GetHashCode()
            && s.subject.GetHashCode()
            && s.grade.GetHashCode();
    }

    public bool Equals(StudentTable s1, StudenTable s2)
    {
        return s1.studentname.Equals(s2.studentname)
            && s1.subject.Equals(s2.subject)
            && s1.grade.Equals(s2.grade);
    }
}

我相信您的设计已损坏,但我会回答您的特定问题。

我假设您正在尝试按名称,主题和年级分组,并检索每个分组的第一位代表性学生。

在这种情况下,您可以按元组进行分组。 元组将免费为您提供EqualsGetHashCode方法,因此可以在组操作中使用。

IEnumerable<Student> distinctStudents = students
                                           .AsEnumerable()
                                           .GroupBy(s => Tuple.Create
                                                               (
                                                                   s.studentname, 
                                                                   s.subject, 
                                                                   s.grade
                                                               )
                                                          )
                                           .Select(g => g.First()); /// Returns the first student of each group

这是一个点网小提琴示例: https://dotnetfiddle.net/7K13DJ

在对象列表上执行Distinct()时,将这些行聚合为较少的行数,并丢弃所有重复项。 因此,您的结果将不再有studentid 要保留studentid属性,您需要使用GroupBy 这将返回给您您的密钥( studentnamesubjectgrade的学生)和原始行的列表。 您可以在此问题中看到一个示例:(使用GroupBy并计算List中的唯一元素 )。

您将有一个studentids列表可供选择,因为可能会有许多行具有相同的studentnamesubjectgrade (否则,您将不会做独特的操作-它们将是唯一的,并且tuple { sudentname, subject, grade }将是自然键 )。 因此,您可能需要问自己的问题是“我需要哪个学生证?”

暂无
暂无

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

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