背景
最近在維護一個舊項目的時候遇到了大段的linq的代碼,本來我可能就是這麼靜靜的看着它了,可是天不從人願,需求的變更剛剛需要處理這段代碼。因為需要求和,去平均等相關的計算,是以開始一波度娘操作。嗯,相關的文章還是不少的,然而基本上就是舉例子作為參考,有以類作為模闆的資料源,也有datatable作為資料源的,但總感覺呼之欲出而不出。最後總算是按需求把求和等做了出來,于數就有了寫點東西的想法。
一個例子
在具體說明怎麼使用linq完成求和,平均等操作之前,我們先來把舉例的相關類介紹一下,很簡單的。我給的是班級和學生兩個模闆類,并以它們作為資料源基礎使用。班級和學生是一對多的關系。具體的模闆類如下
Class.cs
/// <summary>
/// 班級模闆
/// </summary>
public class Class
{
/// <summary>
/// 編号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 班級名稱
/// </summary>
public string BName { get; set; }
}
Students.cs
/// <summary>
/// 學生模闆
/// </summary>
public class Students
{
/// <summary>
/// 編号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 學生名稱
/// </summary>
public string StudentName { get; set; }
/// <summary>
/// 性别,男和女
/// </summary>
public string Gender { get; set; }
/// <summary>
/// 年齡
/// </summary>
public int Age { get; set; }
/// <summary>
/// 班級編号
/// </summary>
public int BId { get; set; }
}
然後我們來看下提供資料源的類,如下
GroupLinqSample.cs
public class GroupLinqSample
{
/// <summary>
/// 得到班級資料源
/// </summary>
/// <returns></returns>
public List<Class> GetClass()
{
return new List<Class>()
{
new Class(){ Id=1,BName="一班"},
new Class(){ Id=2,BName="二班"},
new Class(){ Id=3,BName="三班"},
};
}
/// <summary>
/// 得到學生資料源
/// </summary>
/// <returns></returns>
public List<Students> GetStudents()
{
return new List<Students>()
{
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)。最後的輸出不再多說了。
最後,讓我們看看輸出結果