最近在维护一个旧项目的时候遇到了大段的linq的代码,本来我可能就是这么静静的看着它了,可是天不从人愿,需求的变更刚刚需要处理这段代码。因为需要求和,去平均等相关的计算,所以开始一波度娘操作。嗯,相关的文章还是不少的,然而基本上就是举例子作为参考,有以类作为模板的数据源,也有datatable作为数据源的,但总感觉呼之欲出而不出。最后总算是按需求把求和等做了出来,于数就有了写点东西的想法。
一个例子在具体说明怎么使用linq完成求和,平均等操作之前,我们先来把举例的相关类介绍一下,很简单的。我给的是班级和学生两个模板类,并以它们作为数据源基础使用。班级和学生是一对多的关系。具体的模板类如下
Class.cs
///
/// 班级模板
///
public class Class
{
///
/// 编号
///
public int Id { get; set; }
///
/// 班级名称
///
public string BName { get; set; }
}
Students.cs
///
/// 学生模板
///
public class Students
{
///
/// 编号
///
public int Id { get; set; }
///
/// 学生名称
///
public string StudentName { get; set; }
///
/// 性别,男和女
///
public string Gender { get; set; }
///
/// 年龄
///
public int Age { get; set; }
///
/// 班级编号
///
public int BId { get; set; }
}
然后我们来看下提供数据源的类,如下
GroupLinqSample.cs
public class GroupLinqSample
{
///
/// 得到班级数据源
///
///
public List GetClass()
{
return new List()
{
new Class(){ Id=1,BName="一班"},
new Class(){ Id=2,BName="二班"},
new Class(){ Id=3,BName="三班"},
};
}
///
/// 得到学生数据源
///
///
public List GetStudents()
{
return new List()
{
new Students(){Id=1,StudentName="学生1",Age=19,Gender="男",BId=1},
new Students(){Id=2,StudentName="学生2",Age=15,Gender="男",BId=1},
new Students(){Id=3,StudentName="学生3",Age=17,Gender="女",BId=2},
new Students(){Id=4,StudentName="学生4",Age=18,Gender="男",BId=3},
new Students(){Id=5,StudentName="学生5",Age=18,Gender="女",BId=1},
new Students(){Id=6,StudentName="学生6",Age=16,Gender="男",BId=3},
new Students(){Id=7,StudentName="学生7",Age=19,Gender="女",BId=3},
new Students(){Id=8,StudentName="学生8",Age=15,Gender="女",BId=1},
new Students(){Id=9,StudentName="学生9",Age=18,Gender="男",BId=2},
new Students(){Id=10,StudentName="学生10",Age=19,Gender="女",BId=2},
new Students(){Id=11,StudentName="学生11",Age=17,Gender="男",BId=1},
new Students(){Id=12,StudentName="学生12",Age=16,Gender="男",BId=3},
};
}
}
具体的linq实现,我放在了一个控制台程序中,不多说,先上代码。
static void Main(string[] args)
{
var lstCls = new GroupLinqSample().GetClass();
var lstStu = new GroupLinqSample().GetStudents();
var query = from s in lstCls
join t in lstStu on s.Id equals t.BId
group new { t.Age } by new { s.BName } into g
select new
{
ClassName = g.Key.BName,
AvgAge = g.Average(x => x.Age)
};
foreach (var item in query)
{
Console.WriteLine("班级:{0},平均年龄:{1}",item.ClassName,item.AvgAge);
}
Console.ReadKey();
}
从上面的代码中可以看出,我们是为了得到每个班级的平均年龄。而对于linq来说,想要使用sum等方法,就必须要分组(group)。所以我们需要把想要进行求和、取平均等操作的列放到group的后面,如group new { t.Age } ;而by后面放的是分组的列,如by new { s.BName } ,即说明是以班级名称来分组,对年龄进行求和、取平均的操作。当然不要忘记最后加上into g ,g是随便取的变量名称,因为这个在下面的select中需要使用。
现在来看select中内容,作为分组标准的班级名称字段(BName)必须使用 g.Key.BName的形式给出;而年龄的操作就简单了,直接进行求和、取平均等操作即可,如 g.Average(x => x.Age)。最后的输出不再多说了。
最后,让我们看看输出结果