天天看點

Linq中Average,Sum等方法的使用解析背景一個例子

背景

最近在維護一個舊項目的時候遇到了大段的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)。最後的輸出不再多說了。

最後,讓我們看看輸出結果

Linq中Average,Sum等方法的使用解析背景一個例子