区别在于IQueryable而不是List <t> ??为什么呢?</T>

时间:2012-06-21 13:53:20

标签: linq distinct

enter image description here

First Table是View,Second是我想要的结果

以下查询工作正常

List<BTWStudents> students = (from V in db.vwStudentCoursesSD
        where classIds.Contains(V.Class.Value)
        select new BTWStudents
                    {
                    StudentId = V.StudentId
                    Amount= V.PaymentMethod == "Cashier Check" ? V.Amount: "0.00"
                    }).Distinct().ToList();

但我将其更改为List以添加字符串格式(见下文)

List<BTWStudents> students = (from V in db.vwStudentCoursesSD
        where classIds.Contains(V.Class.Value)
        select new {V}).ToList().Select(x => new BTWStudents
                    {
                    StudentId = V.StudentId
                    Amount= V.PaymentMethod == "Cashier Check" ? String.Format("{0:c}",V.Amount): "0.00"
                    }).Distinct().ToList();

通过第二次查询,我得到了这个

enter image description here

为什么在第二个查询中明显不起作用?

3 个答案:

答案 0 :(得分:0)

尝试此操作(将您的独特内容移至第一个查询并更正了您的错误if / then / else):

List<BTWStudents> students = (from V in db.vwStudentCoursesSD
    where classIds.Contains(V.Class.Value)
    select new {V}).Distinct().ToList().Select(x => new BTWStudents
                {
                classId = V.Class.HasValue ? V.Class.Value : 0,
                studentName = V.StudentName,          
                paymentAmount = V.PaymentMethod == "Cashier Check" ? String.Format("{0:c}",x.V.AmountOwed): "0.00"
                }).ToList();

答案 1 :(得分:0)

使用对象时(在您的情况下是一个包​​装的匿名类型,因为您使用的是Select new {V}而不是Select V),Distinct在进行比较时会调用object.Equals。在内部,它检查对象的哈希码。在这种情况下,您会发现,即使字段包含相同的值,两个对象的哈希码也是不同的。要解决此问题,您需要在对象类型上重写Equals,或者将自定义IEqualityComparer实现传递给Distinct重载。您应该能够在线搜索“Distinct IEqualityComparer”。

答案 2 :(得分:0)

如果您通过StudentID Distinct

,可以一起使用Group
var studentsGroupedByPayment =
    (from V in db.vwStudentCoursesSD
    where classIds.Contains(V.Class.Value)
    group V by V.StudentId into groupedV
    select new
    {
        StudentID = groupedV.Key,
        Amount = string.Format("{0:C}",
                      groupedV.First().PaymentMethod == "Cashier Check" ?
                      groupedV.First().Amount : 0.0)
    }
    ).ToList();