在linq group by子句中使用变量

时间:2014-11-11 09:50:58

标签: c# linq

假设我有一个包含多个列的表(学生,老师,主题,标记),我想将这些列中的每一列与具有相同列的另一个表(使用sum(标记))进行比较。

我有以下方法,列名作为参数,然后在group by子句中使用。

public List<AllMarks> RIMarks(string filter)
{
  var MarkTable = from p in MainDB.classTable
                  let fil = filter
                  group p by new { fil } into g
                  select new AllMarks
                  {
                    Column = g.Key.fil,
                    Marks = g.Sum(f => f.Mark)
                  };

  List<AllMarks> lstRI = MarkTable.ToList();
  return lstRI;
}

public void Test()
{
  var filter = new string[] {"Student", "Teacher", "Subject"}
  foreach (f in filter) 
  {
    // Call RIMarks(f) and do something
  }
}

我的桌子中有许多不同的学生,但是使用这种方法,我得到的只是一行带有总和(第一个过滤标准的标记(所有学生)(这是学生)并且它实际上没有分组学生。

如何在linq groupby子句中使用局部变量?

更新: 样本数据库:

Student    Teacher    Subject    Marks
stu1       teac1      sub1       23
stu1       teac1      sub1       45
stu2       teac2      sub2       34 

2 个答案:

答案 0 :(得分:2)

您尝试按照您拥有的某个数据对象的特定属性的名称进行分组。 您希望反映所需字段的属性,然后按该字段的值进行分组。 您不能只提供名称,因为过滤器不起作用,它只会对整个集合进行分组。

在LinqPad中测试一下。

你所拥有的是在分组上总结的分数,不确定你是否想要平均值

你在这里所拥有的应该会让你获得平均值。

void Main()
{
    var mySchool = new List<School>{
    new School{Student = "Student A", Teacher = "Teacher A", Subject = "Math", Marks = 80},
    new School{Student = "Student B", Teacher = "Teacher A", Subject = "Math", Marks = 65},
    new School{Student = "Student C", Teacher = "Teacher A", Subject = "Math", Marks = 95},
    new School{Student = "Student A", Teacher = "Teacher B", Subject = "History", Marks = 80},
    new School{Student = "Student B", Teacher = "Teacher B", Subject = "History", Marks = 100},
    };

    GroupByFilter("Student", mySchool);
    GroupByFilter("Teacher", mySchool);
    GroupByFilter("Subject", mySchool);
}

public void GroupByFilter(string filter, List<School> school)
{
    PropertyInfo prop = typeof(School).GetProperties()
                                  .Where(x => x.Name == filter)
                                  .First();

    var grouping = from s in school
                   group s by new {filter = prop.GetValue(s)} into gr
                   select new {
                    Filter = gr.Key.filter,
                    Marks = gr.Sum(x => x.Marks)
                   };
    grouping.Dump(); // this is linqpad specific
}

// Define other methods and classes here
public class School{
    public string Student {get;set;}
    public string Teacher {get;set;}
    public string Subject {get;set;}
    public int Marks {get;set;}
}

结果

按学生分组

过滤标记

学生A 160

学生B 165

学生C 95


按教师分组 过滤标记

老师A 240

老师B 180


按主题分组 过滤标记

数学240

历史180

答案 1 :(得分:0)

请尝试以下代码。

public List<AllMarks> RIMarks(string filter)
{
if (filter == "Student") {
 var MarkTable = from p in MainDB.classTable
                        group p by new { p.Student} into g
                        select new AllMarks
                             {
                                 Column = g.Key.fil,
                                 Marks = g.Sum(f => f.Mark)
                             };

    }
 else if (filter == "Teacher") {
   var MarkTable = from p in MainDB.classTable
                        group p by new { p.Teacher} into g
                        select new AllMarks
                             {
                                 Column = g.Key.fil,
                                 Marks = g.Sum(f => f.Mark)
                             };
}
 else if (filter == "Subject") {
    var MarkTable = from p in MainDB.classTable
                        group p by new { p.Subject} into g
                        select new AllMarks
                             {
                                 Column = g.Key.fil,
                                 Marks = g.Sum(f => f.Mark)
                             };
}
}