0

如果这是重复的,我很抱歉;我已经完成了我的搜索,但我已经弄清楚要搜索什么。

假设您有一个学生数据库,并且您想根据性别平均他们的分数。对于您的标准问题关系数据库,这非常简单。它可能需要一个带有显式连接的查询,或者您可能只使用导航属性或其他东西,但它看起来有点像这样:

var averageScore = db.Grades
    .Where(grade => grade.Student.Gender == selectedGender)
    .Average();

但是,如果您连接到基于文档的系统,而您的数据结构只是一个 Student 对象,其中嵌入了一组 Grade 对象,该怎么办?

var averageScore = db.Students.GroupBy(student => student.Gender)
    .ThisDoesNotWork(no => matter.What);

我已经尝试了三打不同的方法来做一个 GroupBy,它设法将值集合转换为共享一个公共键的单个值集合,但它们都没有奏效。我的大部分尝试都涉及在 GroupBy 中尝试 SelectMany,并且——如果可能的话——让我们说编译器不喜欢我的床边方式。

编辑:不确定“格式”是什么意思。我们正在谈论的数据结构只是一个以集合作为其成员之一的类。

class Student
{
    public string Name { get; set; }
    public Gender Gender { get; set; }
    public ICollection<int> Grades { get; set; }
}
4

2 回答 2

1

SelectMany将为您展平集合。

var average = db.Students
    .Where(s => s.Gender == selectedGender)
    .SelectMany(s => s.Grades)
    .Average();

另一方面,GroupBy将特定元素组合在一起。所以,如果你想按性别分组:

var averages = db.Students
    .GroupBy(
        s => s.Gender,
        (gender, group) => group
            .SelectMany(s => s.Grades)
            .Average());

“组”是一个 IEnumerable,即。适合每个组的所有学生。

于 2013-10-11T23:40:45.930 回答
0

Rich 的回答让我更加努力地思考SelectMany()(加上我下班并且很无聊),所以我做了更多的工作,这就是我所拥有的:

var averagesByGender = db.Students
    .SelectMany(
        student => student.Grades,
        (student, grade) => new { Gender = student.Gender, Grade = grade })
    .GroupBy(
        record => record.Gender,
        record => record.Grade)
    .Select(group => new { group.Key, Average = group.Average() });

SelectMany()工作方式与任何 SQL 数据库中的连接语句非常相似:每个年级获得一条记录以及相关的学生信息,然后您可以从那里以老式方式查询您想要的任何内容(或者,如我的示例,您可以为所代表的每种性别获得一个结果)。

唯一的问题是,显然,这相关了……就像在 RavenDB 中一样,它拒绝尝试将其转换为查询。幸运的是,如果你把它藏在后面,那就无关紧要了.ToList()。想知道它是否会以与 MongoDB 相同的方式工作。

于 2013-10-12T02:50:21.387 回答