星星之火

燎原之势不可挡
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.NET知识梳理——7.Linq

Posted on 2020-03-09 21:22  星星之火116  阅读(182)  评论(0编辑  收藏  举报

1. Linq

Linq 其实就是把对数据操作的通用部分完成,把可变的交给委托,使用者只用关心可变部分,其实Linq就是这么一个封装。

1.1        Linq常用方法介绍

1.1.1  Where

List<Person> list = new List<Person>()

            {

                new Person(){ Id=1,Name="今天",Age=10,TypeId=1},

                new Person(){ Id=2,Name="明天",Age=15,TypeId=1},

                new Person(){ Id=3,Name="昨天",Age=20,TypeId=1},

                new Person(){ Id=4,Name="后天",Age=25,TypeId=1},

                new Person(){ Id=5,Name="张天一",Age=10,TypeId=1},

                new Person(){ Id=6,Name="王飞",Age=15,TypeId=1},

                new Person(){ Id=7,Name="李琦",Age=20}};

var result = list.Where<Person>(item => item.Age < 15);

1.1.2  Select

var result=list.Select(item => new { Name = item.Name, Age = item.Age })//投影

1.1.3  Join

默认为inner join

List<PType> pTypeList = new List<PType>()

            {

               new  PType(){ Id=1,Name="少年"},

               new  PType(){ Id=2,Name="青年"},

               new  PType(){ Id=3,Name="中年"}

            };

  var reuslt = from p in list

                             join pt in pTypeList on p.TypeId equals pt.Id

                             select new

                             {

                                 Name = p.Name,

                                 Type = pt.Name

                             };

var result1 = list.Join(pTypeList, p => p.TypeId, pt => pt.Id, (p, pt) => new

                {

                    Name = p.Name,

                    Type = pt.Name

                });

左连接

var result0 = from p in list

                             join pt in pTypeList on p.TypeId equals pt.Id

                             into pptList

                             from ppt in pptList.DefaultIfEmpty()

                             select new

                             {

                                 Name =p.Name,

                                 Type = (ppt!=null?ppt.Name:"无")

                             };

 

  var result1 = list.Join(pTypeList, p => p.TypeId, pt => pt.Id, (p, pt) => new

                {

                    Name = p.Name,

                    Type = pt.Name

                }).DefaultIfEmpty();//这种形式如果关联不上,则该条数据不存在

 

右连接把表的顺序调整即可。

1.1.4  Group

var gList = list.GroupBy(item => item.Age)//按年龄分组

                .Select(item => new { Age = item.Key, Count = item.Count() });//求个年龄人数

1.1.5  OrderBy

var result=list.OrderBy(item => item.Age)//升序排列

                .OrderByDescending(item => item.Age)//降序排列

                .Skip(1)//跳过几条

                .Take(5);//取几条

 

1.2        Linq to everything

1.2.1  Linq To Object

在Enumerable类,针对IEnumerable数据(指的是内存数据)进行的一些列的封装。

1.2.2  Linq To Sql 

在Queryable类,针对IQueryable数据,操作数据库

1.2.3  Linq To XML 

封装一下通用的对XML文件的操作,可变的通过委托来传递

1.3        Yield迭代器

含有yield的函数说明它是一个生成器,而不是普通的函数。当程序运行到yield这一行时,该函数会返回值,并保存当前域的所有变量状态;等到该函数下一次被调用时,会从上一次中断的地方开始执行,一直遇到下一个yield, 程序返回值, 并在此保存当前状态; 如此反复,直到函数正常执行完成。yield跟IEnumerable配对使用。

迭代器模式是设计模式中行为模式(behavioral pattern)的一个例子,他是一种简化对象间通讯的模式,也是一种非常容易理解和使用的模式。简单来说,迭代器模式使得你能够获取到序列中的所有元素 而不用关心是其类型是array,list,linked list或者是其他什么序列结构。这一点使得能够非常高效的构建数据处理通道(data pipeline)--即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是LINQ的核心模式。

在.NET中,迭代器模式被IEnumerator和IEnumerable及其对应的泛型接口所封装。如果一个类实现了IEnumerable接 口,那么就能够被迭代;调用GetEnumerator方法将返回IEnumerator接口的实现,它就是迭代器本身。迭代器类似数据库中的游标,他是 数据序列中的一个位置记录。迭代器只能向前移动,同一数据序列中可以有多个迭代器同时对数据进行操作。

示例:

一般方法:

  public IEnumerable<int> CommonMethod()

        {

            List<int> result = new List<int>();

            int counter = 0;

            int r = 1;

            while(counter++<5)

            {

                Thread.Sleep(1000);

                Console.WriteLine($"获取{counter}次数据");

                r = r * 2;

                result.Add(r);

            }

            return result;

        }

Yield方法:

        public IEnumerable<int> YieldMethod()

        {

            int counter = 0;

            int r = 1;

            while(counter++<5)

            {

                Thread.Sleep(1000);

                Console.WriteLine($"获取{counter}次数据");

                r = r * 2;

                yield return r;

            }

        }