C# &引用;分组方式;基于文档的存储中的实体?

C# &引用;分组方式;基于文档的存储中的实体?,c#,linq,mongodb,group-by,ravendb,C#,Linq,Mongodb,Group By,Ravendb,如果这是重复的,我道歉;我已经完成了我的搜索任务,但我已经找到了要搜索的内容 假设你有一个学生数据库,你想根据性别平均他们的分数。对于您的标准问题关系数据库,这非常简单。它可能需要一个带有显式联接的查询,或者您可以只使用导航属性或其他东西,但它看起来有点像这样: var averageScore = db.Grades .Where(grade => grade.Student.Gender == selectedGender) .Average(); 但是,如果您连接到

如果这是重复的,我道歉;我已经完成了我的搜索任务,但我已经找到了要搜索的内容

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

var averageScore = db.Grades
    .Where(grade => grade.Student.Gender == selectedGender)
    .Average();
但是,如果您连接到一个基于文档的系统,而您的数据结构只是一个学生对象,其中嵌入了一组成绩对象,该怎么办

var averageScore = db.Students.GroupBy(student => student.Gender)
    .ThisDoesNotWork(no => matter.What);
我尝试了三十多种不同的方法来创建一个GroupBy,该GroupBy能够将值集合转换为共享一个公共键的单个值集合,但没有一种方法有效。我的大多数尝试都涉及到在GroupBy中尝试SelectMany,如果可能的话,让我们说编译器不喜欢我的床边方式

编辑:不确定你所说的“格式”是什么意思。我们所说的数据结构只是一个类,其中一个成员是集合

class Student
{
    public string Name { get; set; }
    public Gender Gender { get; set; }
    public ICollection<int> Grades { get; set; }
}
班级学生
{
公共字符串名称{get;set;}
公共性别{get;set;}
公共ICollection等级{get;set;}
}
将为您展平收藏

var average = db.Students
    .Where(s => s.Gender == selectedGender)
    .SelectMany(s => s.Grades)
    .Average();
另一方面,将特定元素分组在一起。因此,如果您想按性别对所有人进行分组:

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

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

里奇的回答让我更加认真地思考
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数据库中的join语句非常相似:每个年级都有一条记录,其中包含相关的学生信息,从那里你可以用老式的方式查询任何你想查询的内容(或者,如我的示例中所示,你可以为所代表的每个性别获得一个结果)


唯一的问题是,很明显,这太关系化了。。。正如RavenDB拒绝尝试将其转换为查询一样。幸运的是,如果您将它隐藏在
.ToList()
后面,那就无关紧要了。不知道它是否与MongoDB的工作方式相同。

文档的格式是什么?如果您的实体不重写Equals和GetHash,它将不工作。在最近的一篇博文中,我对ExpandoObjects也有类似的问题。是否可以提供学生背后的代码?请尝试从控制台使用聚合框架,以查看是否可以获得所需的输出。如果你不能,那么与LINQ合作就没有任何希望了。如果你能——那么,你仍然不能使用LINQ,但你至少可以得到你想要的数据。打赌LINQ是不好的p这实际上不起作用(编译时问题;如果你稍微编辑一下,可能会有问题?),但我发现了一些有效的方法。我无法让编译器接受
GroupBy
中的第二个lambda,我只是从这里复制/粘贴到那里,但这可能就是问题所在。我以前的尝试有错误的签名(只有一个输入而不是两个),IntelliSense可能会陷入困境,认为我没有改变这一点。不管怎样,我从来没有试过打F5,因为我很傻。你的答案很好,我接受了里奇的答案。我本来想删除这个,但我还是留下了它,因为直到昨天,我还不知道你可以这样使用
SelectMany
,也许它会在某个时候帮助其他人。