美文网首页
Lession12-LINQ

Lession12-LINQ

作者: 任人渐疏_Must | 来源:发表于2021-06-16 08:41 被阅读0次

    LINQ简介

     /*
         * 查询是一种从数据源检索数据的表达式。 查询通常用专门的查询语言来表示。 随着时间的推移,
         * 人们已经为各种数据源开发了不同的语言;例如,用于关系数据库的 SQL 和用于 XML 的 XQuery。
         * 因此,开发人员对于他们必须支持的每种数据源或数据格式,都不得不学习一种新的查询语言。 
         * LINQ 通过提供处理各种数据源和数据格式的数据的一致模型,简化了这一情况。 在 LINQ 查询中,
         * 始终会用到对象。 可以使用相同的基本编码模式来查询和转换 XML 文档、SQL 数据库、ADO.NET 数据集、
         * .NET 集合中的数据以及 LINQ 提供程序可用的任何其他格式的数据。
         * 
         * Linq to object (数组、list集合)--内存里面的数据
         * Linq to sql (查询数据用的)--在数据库数据
         * Linq to Xml  查询XML文件
         * 
         * 所有 LINQ 查询操作都由以下三个不同的操作组成:
         *  1.获取数据源。
         *  2.创建查询。
         *  3.执行查询
         *  
         *  1.LINQ查询表达式
         *  
         *  from i in list
         *                  where i < 10
         *                  orderby i
         *                  select i;
         *子句中from,where,orderby selece关键字都是linq预定义的关键字
         *所有的Linq查询表达式都必须以from子句开始,以select或者group 子句结束
         *在开头和结束子句之间,可以使用where,orderby join等其他from子句
         *
         *Linq查询表达式开头的from子句用于指定数据源 格式:
         *from [单个数据源元素] in [数据源]
         *
         *linq查询表达式结束的select子句用于指定返回的目标数据。格式:
         *select[目标元素]
         *
         *  
         *  
         * 
         */
        class Program
        {
            static void Main(string[] args)
            {
                #region linq查询表达式
                //练习1 数组
                //Array
                //获取数组数据源
                int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
              
    
                //创建查询
                IEnumerable<int> numQuery =
                     from num in numbers
                     where (num % 2) == 0
                     select num;   //用于指定返回的目标数据
                   
                //执行查询
                foreach (int num in numQuery)
                {
                    Console.WriteLine("{0}", num);
                }
    
                Console.WriteLine("---------------------------");
    
                //list数据源 List<int>数据类型,实现了IEnumerable<T>接口,所以可以使用Linq
                List<int> list = new List<int> { 1, 2, 4, 3, 9, 5, 43, 21 };
                var _list = from i in list
                            where i < 10
                            orderby i
                            select i;
                foreach (var item in _list)
                {
                    Console.WriteLine( item);
                }
    
                #endregion
    
    
                Console.ReadKey();
    
            }
        }
    
    

    编写一个扩展方法

    /*
         * 扩展方法
         * 静态类里的静态方法,参数列表最前面加个this+要扩展到的类型
         * 使用场景:在不修改源码的情况下为其他类型修改方法
         * 
         */
        class Program
        {
            static void Main(string[] args)
            {
                Cal cal = new Cal();
                Console.WriteLine(cal.AddNew(1, 2, 4));
                Console.ReadKey();
            }
        }
    
        public class Cal
        {
            public int Add(int a, int b)
            {
                return a + b;
            }
            //public int Add(int a, int b, int c)
            //{
            //    return a + b + c;
            //}
        }
    
        static class CalExtend
        {
            public static int AddNew(this Cal cal,int a,int b,int c)
            {
                return a + b + c;
            }
        }
    
    
    

    LINQ查询方法

     /*
         * public static IEnumerable<TSource> Where<TSource>
         * (this IEnumerable<TSource> source, Func<TSource, bool> predicate);
         * 
         * Func<TSource, bool>:是一个委托,此委托返回类型是bool,传入的参数数据类型为数据源中元素的数据类型
         * Where(i => i < 10):这是lambda表达式,传入的参数为TSource类型的参数为i ,如果i满足小于10返回true,则保留元素
         * 返回false,即将元素过滤
         * 
         * 扩展方法
         * 静态类里的静态方法,参数列表最前面加个this+要扩展到的类型
         * 使用场景:在不修改源码的情况下为其他类型修改方法
         * 
         */
    
        class Program
        {
            static void Main(string[] args)
            {
                //数据源
                List<int> list = new List<int> { 1, 2, 4, 3, 9, 5, 43, 21 };
                var _list = list.Where(i => i < 10).OrderBy(i => i);
                foreach (var item in _list)
                {
                    Console.WriteLine(item);
                }
                Console.ReadKey();
            }
        }
    
    

    LINQ查询的延迟加载

     /*
         * 虽然我们往list里面添加了两个新的元素,但是没有对_list进行操作
         * 如果LINQ查询是将结果查询到后,存储在_list指向的内存中,那么两次遍历结果应该一样
         * 但两个遍历结果却不同 这是为什么?
         * 我们可以将LINQ查询仅仅理解成一个表达式,编译的时候它被存于程序集中,程序运行时,它并没有被拿去执行对数据源的查询
         * 而是当我们去遍历或者读取数据结果时,这个表达式才会被执行去查询数据源,这也就是所谓的查询延迟加载
         * 
         * 只有当foreach的时候,才会逐个返回结果中的元素
         * 因为类似Where的Linq操作,不是在内存里重新开辟内存存放结果,而是只保存了查询的命令,
         * 这样我们可以在后面继续增加新的命令形成一系列的组合操作,不至于每次查询都浪费资源生成新的中间结果。
         * 
         * 当我们对查询结果进一步调用ToArray()、ToList()方法后,返回的数组或者集合会丧失延迟加载的特征
         * 因为这个两个操作会在内存在开辟空间,并需要将查询结果存入内存中
         * ToList()之后,LINQ查询被执行了,查询到的结果被存储在了内存中,成为了新的数据源
         * 
         * 然而,也有少数的Linq命令是即时加载的,比如Count、First、Last等方法。因为这些方法本身就涉及到了遍历各个元素,
         * 既然内部需要foreach遍历,自然就不是延迟加载了。
         * 
         */
        class Program
        {
            static void Main(string[] args)
            {
                List<int> list = new List<int> { 1, 2, 4, 3, 9, 5, 43, 21 };
                var _list = list.Where(i => i < 10).OrderBy(i => i);
                //var _list = list.Where(i => i < 10).OrderBy(i => i).ToList();
                Console.WriteLine("第一次遍历_list");
                foreach (var item in _list)
                {
                    Console.WriteLine(item);
                }
                Console.WriteLine("-----------------------------");
                list.Add(8);
                list.Add(6);
                Console.WriteLine("第二次遍历_list");
                foreach (var item in _list)
                {
                    Console.WriteLine(item);
                }
    
                Console.ReadKey();
    
            }
        }
    
    

    Linq标准查询操作符

     class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person("贾宝玉", 16);
                Person p2 = new Person("林黛玉", 15);
                Person p3 = new Person("薛宝钗", 15);
                Person p4 = new Person("王熙凤", 22);
    
                List<Person> list = new List<Person>() { p1, p2, p3, p4 };
                List<string> listName = list.Where(p => p.Age > 15) //过滤掉年龄不超过15岁的人
                    .OrderByDescending(p => p.Age)//按照年龄的降序排列
                    .Select(p => p.Name)//将查询结果投射成名字
                    .ToList(); //将结果转成集合
                Console.WriteLine($"年龄超过15岁的共有{listName.Count()}人,按年龄由大到小进行排序结果如下:");
                //遍历集合
                foreach (var name in listName)
                {
                    Console.WriteLine(name);
                }
                Console.WriteLine("--------------------------------");
                Console.WriteLine($"所有4个人的平均年龄是{list.Average(p=>p.Age)}岁");
                Console.WriteLine($"所有4个人的总年龄是{list.Sum(p => p.Age)}岁");
                Console.WriteLine($"所有4个人的年龄最大的{list.Max(p => p.Age)}岁");
    
                Console.WriteLine("-----------------------------------------");
                //获取唯一一个年龄大于16岁的人,如果多个会抛出异常
                Person pUpper16 = list.Single(p => p.Age > 16);
                Console.WriteLine($"唯一一个年龄大于16岁的是{pUpper16.Age}岁的{pUpper16.Name}");
                Console.ReadKey();
    
            }
        }
    
        public class Person
        {
            public Person(string name,int age)
            {
                Name = name;
                Age = age;
            }
           
            public string Name { get; set; }
            public int Age { get; set; }
        }
    
    

    LinqToXML

    ?xml version="1.0" encoding="utf-8" ?> 
    <!-- xml 可扩展的标记语言 解决HTML不可扩展的问题,作用:保存或传输数据,不是用来显示数据的。-->
    <Hopu>
      <Specialty SpecialtyName="1">
        <Class>物联网1班</Class>
        <Class>物联网2班</Class>
      </Specialty>
      <Specialty SpecialtyName="2">
        <Class>云计算1班</Class>
        <Class>云计算2班</Class>
      </Specialty>
      <Specialty SpecialtyName="3">
        <Class>电商1班</Class>
        <Class>电商2班</Class>
        <Class>电商3班</Class>
        <Class>电商4班</Class>
      </Specialty>
    
    </Hopu>
    
    
     /*
         * 我们对XML文件使用LINQ查询操作符,它使用的语法和我们之前对泛型集合进行的LINQ查询使用了where(),select()方法
         * 语法风格一致
         * 但Attribute()和Descendants()方法,时XML的LINQ查询特有的,它们位于System.Xml.Linq命名空间下,需要引入
         * 
         * 
         * 
         */
        class Program
        {
            static void Main(string[] args)
            {
                //加载xml文件,引入命名空间
                XElement root = XElement.Load(@"myxml.xml");
                //使用LINQ查询表达式
                //[speʃəlti]
                var specialties = from specialty in root.Elements("Specialty")
                                  where specialty.Attribute("SpecialtyName").Value == "1"
                                  select specialty;
                foreach (var item in specialties)
                {
                    Console.WriteLine(item);
                }
                Console.WriteLine("-------------------");
                //使用LINQ查询方法Descentdants() [dɪˈsent] 获取所有子代元素
                var classes = specialties.Where(s => s.Attribute("SpecialtyName").Value == "1").Descendants();
    
                foreach (var item in classes)
                {
                    Console.WriteLine(item);
                }
    
    
                Console.ReadKey();
    
            }
        }
    
    

    相关文章

      网友评论

          本文标题:Lession12-LINQ

          本文链接:https://www.haomeiwen.com/subject/ljimeltx.html