LINQ集合操作

LINQ是一个用于操作集合的语法,它能够查询一个集合里的字段,并且能够分组、排序,除此之外还有其他的功能。它的语法规则和SQL语言非常相似。


在一个集合中,我们想要得到集合里满足特定条件下的集合,通常情况下我们会用foreach循环来获取里面的集合。
首先我们先定义两个集合

//武林高手集合
class MartialArtsMaster
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Menpai { get; set; }
        public string Kungfu { get; set; }
        public int Level { get; set; }

        //重写ToString方法
        public override string ToString()
        {
            return $"Id: {Id}, Name: {Name}, Age: {Age}, Menpai: {Menpai}, Kungfu: {Kungfu}, Level: {Level}";
        }
    }

//武学集合
class Kungfu
    {
        public int Id;
        public string Name;
        public int Power;

        public override string ToString()
        {
            return $"Id: {Id}, Name: {Name}, Power: {Power}";
        }
    }

然后在主函数里new两个集合对象

static void Main(string[] args)
        {
            //初始化武林高手
            var masterList = new List<MartialArtsMaster>()
            {
                new MartialArtsMaster() {Id = 1, Name = "黄蓉", Age = 18, Menpai = "丐帮", Kungfu = "打狗棒法", Level = 9},
                new MartialArtsMaster() {Id = 2, Name = "洪七公", Age = 70, Menpai = "丐帮", Kungfu = "打狗棒法", Level = 10},
                new MartialArtsMaster() {Id = 3, Name = "郭靖", Age = 22, Menpai = "丐帮", Kungfu = "降龙十八掌", Level = 10},
                new MartialArtsMaster() {Id = 4, Name = "任我行", Age = 50, Menpai = "明教", Kungfu = "葵花宝典", Level = 1},
                new MartialArtsMaster() {Id = 5, Name = "东方不败", Age = 35, Menpai = "明教", Kungfu = "葵花宝典", Level = 10},
                new MartialArtsMaster() {Id = 6, Name = "林平之", Age = 23, Menpai = "华山", Kungfu = "葵花宝典", Level = 7},
                new MartialArtsMaster() {Id = 7, Name = "岳不群", Age = 50, Menpai = "华山", Kungfu = "葵花宝典", Level = 8},
                new MartialArtsMaster() {Id = 8, Name = "令狐冲", Age = 23, Menpai = "华山", Kungfu = "独孤九剑", Level = 10},
                new MartialArtsMaster() {Id = 9, Name = "梅超风", Age = 23, Menpai = "桃花岛", Kungfu = "九阴真经", Level = 8},
                new MartialArtsMaster() {Id = 10, Name = "黄药师", Age = 23, Menpai = "梅花岛", Kungfu = "弹指神通", Level = 10},
                new MartialArtsMaster() {Id = 11, Name = "风清扬", Age = 23, Menpai = "华山", Kungfu = "独孤九剑", Level = 10}
            };

            //初始化武学
            var KungfuList = new List<Kungfu>()
            {
                new Kungfu() {Id = 1, Name = "打狗棒法", Power = 90},
                new Kungfu() {Id = 2, Name = "降龙十八掌", Power = 95},
                new Kungfu() {Id = 3, Name = "葵花宝典", Power = 100},
                new Kungfu() {Id = 4, Name = "独孤九剑", Power = 100},
                new Kungfu() {Id = 5, Name = "九阴真经", Power = 100},
                new Kungfu() {Id = 6, Name = "弹指神通", Power = 100}
            };
        }

查询

然后我们使用foreach循环来查询武学级别大于8的武林高手

//查询所有武学级别大于8的武林高手
            var res = new List<MartialArtsMaster>();
            foreach (var temp in masterList)
            {
                if (temp.Level > 8)
                {
                    res.Add(temp);
                }
            }

但是使用LINQ能够使代码更加的简洁并且易懂

//使用LINQ查询
            var res = from m in masterList //from后面设置查询的集合
                where m.Level > 8 //where后面跟上查询的条件
                select m.Name; //表示m的结果返回

我们使用扩展方法可以使它更加简洁,写一个方法来存储判断条件,每次要判断的时候就调用这个方法

//扩展方法
            var res = masterList.Where(Test1);

//判断方法
            bool Test1(MartialArtsMaster master)
            {
                if (master.Level > 8) return true;
                return false;
            }

但是写一个判断方法对我们来说,如果条件修改了,那这个方法也需要修改,这时候我们可以使用之前学的Lambda表达式,因为这个判断方法可以作为一个匿名方法,里面的方法体才是对我们有用的。

//Lambda表达式
            var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐帮");

联合查询

前面几个方法都是对一个集合查询,我们还可以使用LINQ对两个集合进行联合查询

//LINQ联合查询
            var res = from m in masterList
                from k in Kungfu
                where m.Kungfu == k.Name && k.Power >= 95
                select m;

然后我们还是使用扩展方法和Lambda表达式来对代码进行优化

//扩展方法——LINQ联合查询
            var res = masterList.SelectMany(m => KungfuList, (m, k) => new {master = m, Kungfu = k})
                .Where(x => x.master.Kungfu == x.Kungfu.Name && x.Kungfu.Power > 95);

这里的代码使用了Func委托,我们可以在代码中查看SelectMany这个方法是如何使用的,否则很难理解这里代码的意思。

联合查询还有另外一种方法:join in集合联合查询

//join in集合联合查询
            var res = from m in masterList
                join k in KungfuList on m.Kungfu equals k.Name
                where k.Power > 95
                select new {master = m,Kungfu=k}; //表示将两个集合结合在一起成为一个新的集合然后返回该集合

排序

我们查询完结果后,可以对结果的某个字段进行排序,默认排序是从小到大,使用descending则倒序

//对查询结果进行排序orderby  倒序descending
            var res = from m in masterList
                where m.Level > 8 && m.Menpai == "丐帮"
                //orderby m.Age descending //倒序
                orderby m.Level,m.Age //按照多个字段排序,若前面的字段属性相同,再对第二个字段进行排序
                select m;

代码优化之后

//扩展方法
            var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐帮").OrderBy(m=>m.Age);
            //按照多个字段排序
            var res = masterList.Where(m => m.Level > 8 && m.Menpai == "丐帮").OrderBy(m => m.Level).ThenBy(m => m.Age);

扩展方法里的多个字段排序,只能使用ThenBy关键字,如果还是使用OrderBy关键字,则会在level排序之后,再根据Age再重新排序。


分组查询

查询完结果之后,我们可以对集合进行分组,只得到自己想要的结果,其余的字段可以忽略

//分组查询 into groups(按照功夫分类)
            var res = from k in KungfuList
                join m in masterList on k.Name equals m.Kungfu
                into groups //分组关键字
                orderby groups.Count()
                //将master=m改成groups.Count()是因为分完组后,
                //master就是作为组来输出了,不再以单个形式出现
                select new {Kungfu = k, count = groups.Count()}; 

我们还可以根据集合里的某个字段进行分组

//按照自身字段分组 group
            var res = from m in masterList
                      group m by m.Menpai
                      into g //将分组完的信息放入g中
                      select new { count = g.Count(), key = g.Key }; //key是指分组所根据的字段,在这里指Menpai这个字段

量词操作符

使用量词操作符我们可以判断这个集合里是否存在某个字段

//Any只需要其中一个字段相同就返回True
            bool result = masterList.Any(m => m.Menpai == "丐帮");
            //All需要全部字段都相同才返回True
            bool result2 = masterList.All(m => m.Menpai == "丐帮");
            Console.WriteLine(result);
            Console.WriteLine(result2);

LINQ的方法还有很多,这些是最常用的,上面的代码得到的结果可以使用foreach遍历返回的集合来输出

foreach (var temp in res)
            {
                Console.WriteLine(temp);
            }

LINQ不仅仅能够对集合进行操作,还能够对XML数据源、Sql Server进行操作,但是微软已不再更新对Sql的操作,所以推荐使用LINQ to Entitles。但是我们最经常使用的还是对内存中的集合的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值