继续过滤/查询组对象?

时间:2015-09-22 18:14:51

标签: c# linq

我有以下查询,该查询返回按Registrations分组的CourseId's列表。

var coursesTest = (from r in db.Registrations
                     group r by r.CourseId into distinctCourses
                     select distinctCourses).ToList();

我想继续查询并过滤掉类似的内容;

var coursesTest = (from r in db.Registrations
                   group r by r.CourseId into distinctCourses
                   from dc in distinctCourses
                   where dc.CourseName != null
                   select new
                   {
                       name = dc.CourseName,
                       Id = dc.CourseId
                   }).ToList();

当我这样做时,我现在得到Registrations的完整记录集......为什么?

5 个答案:

答案 0 :(得分:2)

你想知道为什么不能这样做?尝试在SQL中按照您目前尝试的方式进行操作。您无法选择未在聚合函数内部指定的成员。

此部分from dc in distinctGroups的作用类似于.SelectMany,它会再次破坏您的分组。这就是为什么你让所有成员而不是他们被分组的原因。如果你在编译后打开你的dll,你可以看到它的工作方式。我在这里做了一个例子,这基本上是它在编译后的样子:

ILDASM

如果您想从对象中选择特定属性,则需要在group by部分内对这两个属性进行分组,如下所示:

var coursesTest = (from r in registrations
                   where r.CourseName != null
                   group r by new { r.CourseId, r.CourseName } into distinctCourses
                   select distinctCourses.Key).ToList();

属性Key将包含您在group by案例中创建的匿名类型对象,它将被正确分组。

修改

进一步解释:

这是Linq对SQL的解释,它的行为方式相同。我不确定您对SQL有多熟悉,但是当您编写具有分组依据的查询时,您无法SELECT任何不属于您的内容你的小组是一个聚合函数的一部分。例如COUNT(*)SUM(Something)等。在C#Linq版本中,当您编写group <item> by <property(ies)> into <newGroup>时,newGroup具有Key属性,该属性会自动包含您可以使用的所有元素可能选择那些你在group by内使用的那些。您可以进一步做的只是在这些属性旁边添加一些聚合函数。

一些视觉示例:

SELECT COUNT(*) AS NumberOfCourses, CourseId, CourseName
FROM dbo.Courses
WHERE CourseName IS NOT NULL
GROUP BY CourseId, CourseName

它与此相同:

var result =
    (from c in Courses
     where c.CourseName != null
     group c by new { c.CourseId, c.CourseName } into groupedCourses
     select new { c.Key, NumberOfCourses = c.Count() }).ToList();

因此,group by Key再次包含您可以从初始课程c获得的所有可能属性,这些属性是您在group by中使用的属性。您可以使用它来通过现有集合上的某些聚合函数进一步扩展它,或者将它们全部取回。

答案 1 :(得分:1)

我认为你可能需要这样的东西(所有课程的分组都没有CourseName等于null的项目:

var set = db.Registrations.GroupBy(v => v.CourseId)
    .Where(x => x.All(y => y.CourseName != null))
    .SelectMany(z => z)
    .Select(a => new { Name = a.CourseName, Id = a.CourseId });

如果您只想要所有带有非空Registration的{​​{1}}个对象,那么为什么要将它们组合在一起呢?只需过滤原始列表。

答案 2 :(得分:1)

试试这个:

var coursesTest = (from r in db.Registrations
                   group r by r.CourseId into distinctCourses
                   select distinctCourses)
                  .Select(c => new { Id = c.Key, CourseNames = c.Where(x => x.CourseName != null) });

答案 3 :(得分:1)

对于这么简单的事情似乎过于复杂:

var coursesTest = db.Registrations
  .Where(r=>r.CourseName!=null)
  .Select(r=>new {r.CourseId,r.CourseName})
  .Distinct()
  .ToList();

答案 4 :(得分:-2)

尝试

var coursesTest = (from r in db.Registrations
                 group r by r.CourseId into distinctCourses
                 select distinctCourses).Where(r=>r.dc.CourseName != null).ToList()