C#:LINQ

刚刚接触LINQ,对这个语言集成查询(Language INtegrated Query)还很懵懂,遂记录下学习心得,方便以后查阅。

LINQ的写法形式有点像SQL,但它跟SQL是没有任何关系,它的作用主要就是用来处理对象的集合。

下面以一个简单的例子来展示LINQ的强大之处:

如:我要在一批电影集合中找出票价最便宜的前3部电影,下面的代码是以前的做法形式:

        static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            //用来保存查询结果
            Movie[] ms = new Movie[3];

            //按照价格属性重新排序
            Array.Sort(movies, (item1, item2) => {
                return Comparer<decimal>.Default.Compare(item1.price, item2.price);
            });

            //前3项拿出来
            Array.Copy(movies, ms, 3);

            foreach (var item in ms)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
            }
            Console.ReadLine();
        }
    }
    public class Movie
    {
        public string Name { get; set; }
        public string artist { get; set; }
        public decimal price { get; set; }
    }


现在,我直接用LINQ对此进行处理,看看结果如何:

      static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            var results = from ms in movies
                          orderby ms.price ascending
                          select new { ms.artist, ms.Name, ms.price };
            int i = 0;
            foreach (var item in results)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
                if (i++==2)
                {
                    break;
                }
            }
      
            Console.ReadLine();
        }


可以看到效果是一样的。相比老方式而言,使用LINQ清晰,容易看懂业务,也可以少敲很多繁杂代码。

但是,上面的LINQ也有缺点,就是引入了一个计数变量i,如果不引入,那么foreach会将所有元素打印出来。如果这样的计数变量多了,像什么i,j等乱七八糟的都有了之后,让人看了很是不舒服。怎么办呢?LINQ还有一种写法:

      static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            var results = movies
                .OrderBy(m=>m.price)
                .Take(3)
                .Select(a=>new{a.artist,a.Name,a.price});

            foreach (var item in results)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
            }
            Console.ReadLine();
        }
这样,对于结果,就不用再引入计数器了。 偷笑


还有一个值得一提的就是:LINQ的查询是延迟的,什么意思呢?就拿上面的例子来说,不执行foreach代码,那么上面LINQ的那段查询就不会执行。直到执行了foreach(即IEnumerable<T>结果中的条目被枚举时)才会执行查询。

可以测试一下:

       static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            var results = movies
                .OrderBy(m=>m.price)
                .Take(3)
                .Select(a=>new{a.artist,a.Name,a.price});

            //加了这一句
            movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

            foreach (var item in results)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
            }
            Console.ReadLine();
        }
查询结果是:


可见,上面的LINQ查询是在新加的语句执行之后才执行的。

那如果我不想让LINQ查询在新加的语句执行之后才执行,我想让它立刻执行,怎么弄呢?

很简单,在新加的语句之前,执行一次foreach,如下:

        static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            var results = movies
                .OrderBy(m=>m.price)
                .Take(3)
                .Select(a=>new{a.artist,a.Name,a.price});

            foreach (var item in results)
            {
                Console.WriteLine(item.artist + "----" + item.Name + "----" + item.price);
            }
            //加了这一句
            movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

            foreach (var item in results)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
            }
            Console.ReadLine();
        }

可以看到结果:LINQ查询了两遍!!!


其实除了foreach,还是有其它方式可以让LINQ立刻执行,比如:使用非延迟的扩展方法(如下面的Sum方法)。

       static void Main(string[] args)
        {
            //构造一个对象集合
            Movie[] movies =
            {
                new Movie{Name="晚秋",artist="汤唯",price=25.5M},
                new Movie{Name="少林足球",artist="周星驰",price=35.7M},
                new Movie{Name="叶问",artist="甄子丹",price=15.5M},
                new Movie{Name="无间道",artist="刘德华",price=45.5M},
                new Movie{Name="霸王别姬",artist="张国荣",price=50M},
                new Movie{Name="邻家特工",artist="成龙",price=25.5M}
            };

            var results = movies
                .OrderBy(m=>m.price)
                .Take(3)
                .Select(a=>new{a.artist,a.Name,a.price});

            //LINQ执行查询
            var sum = movies.Sum(e => e.price);
            Console.WriteLine("Sum:"+sum);

            //加了这一句
            movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

            //LINQ执行查询
            foreach (var item in results)
            {
                Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
            }

            //LINQ执行查询
            var sum1 = movies.Sum(e => e.price);
            Console.WriteLine("Sum:" + sum1);

            Console.ReadLine();
        }
结果如下,可以看到LINQ执行了3次查询!!!


关于LINQ暂时就先记录到这啦。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值