基本的LINQ操作

LINQ to Object:

LINQ(语言集成查询):一种强类型查询语言。可以用于多种数据库存储,甚至与关系数据库完全无关的存储。
实质:LINQ查询操作符是调用System.Linq.Enumerable类中的方法的一种简便形式,c#编译器将所有的LINQ操作都翻译为
           对Enumerable类中方法的调用,因此大多数情况下linq查询的返回值为实现了Ienumerable<T>接口的类型

延迟执行:我们在迭代LINQ查询内容之前,LINQ查询并没有真正的执行而是在迭代数据项时运行

            int[] nums = { 10, 15, 8, 7, 5, 6, 9 };
            //linq查询获得小于10的数
            var result = from n in nums where n < 10 select n;

            foreach (var item in result)
            {
                 Console.WriteLine("{0}<10",item);
            }
            Console.WriteLine();
        
            //修改发生在LINQ查询之后
            nums[0] = 1;
            //遍历LINQ结果内容,会发现修改起作用了
            foreach (var item in result)
            {
                Console.WriteLine("{0}<10", item);
            }

立即执行:Enumerable定义了如ToArray<T>()、ToList<T>等扩展方法.当LINQ查询使用这些方法时便会产生数据快照。然后就可以对这些快照数据进行独立的操作了

            int[] nums = { 10, 15, 8, 7, 5, 6, 9 };
            //linq查询获得小于10的数,使用ToArray<int>()方法获得数据快照,返回int[]数组
            int[] result = (from n in nums where n < 10 select n).ToArray<int>();

            foreach (int item in result)
            {
                 Console.WriteLine("{0}<10",item);
            }
            Console.WriteLine();
        
            //修改发生在LINQ查询之后
            nums[0] = 1;
            //遍历LINQ结果内容,此时修改不会更改result的结果
            foreach (var item in result)
            {
                Console.WriteLine("{0}<10", item);
            }

对非泛型集合使用LINQ查询:linq查询是基于IEnumerable<T>接口的,如果要实现非泛型的LINQ查询则需要使用

                                                Enumerable.OfType<T>()方法进行转换
           
            1.使用Enumerable.OfType<T>()方法进行转换

            //非泛型的学生集合
            ArrayList student = new ArrayList()
            {
                new Student {StuNo=1,StuName="rock",Age=18,StuClasses=1 },
                new Student { StuNo=2,StuName="jason",Age=19,StuClasses=1},
                new Student { StuNo=3,StuName="FL",Age=18,StuClasses=1}
            };
            //把ArrayList转换成一个兼容于IEnumerable<T>的类型
            var students = student.OfType<Student>();
            //建立兼容类型的查询表达式
            var bigStudents = from s in students where s.Age > 18 select s;

            foreach (var item in bigStudents)
            {
                Console.WriteLine("{0} age is biger than other",item.StuName);
            }

            2.使用OfType<T>()筛选数据:过滤出那些类型不同于迭代操作中所指定类型的元素(基于类型的筛选)

            static void OfTypeAsFilter()
            {
                ArrayList myStuff=new ArrayList();
                myStuff.AddRange(new Object[] {10,400,8,false,"stringname"});
                //筛选出myStuff中的整数
                var Ints=myStuff.OfType<int>();
                //此时会输出10 400 8
                foreach(int i in Ints)
                {
                   Console.WriteLine("Int Value : {0}",i);
                }
            }

C#LINQ查询操作符
1.基本的选择语法:


   //in 后面的数据容器可以是数组,集合或XML文档
   var result= from matchingItem in container select machingItem;

2.获取数据子集:


   //where 后面是结果为布尔值得表达式,可以是任意合法的C#语句表达式
   var result=from item in container where BoolenExpression select item
   例:
   var bigStudents = from s in students where s.Age > 18 && s.StuNo==2 select s;

3.使用Enumerable获取总数(聚合操作):使用扩展方法Count(); 额外的聚合操作还有Average()、Max()、Min()、Sum()
   如:


   int sum = (from s in students where s.Age > 18 && s.StuNo == 2 select s).Count();

4.对表达式进行排序:
   如:


   var bigStudents = from s in students where s.Age == 18 orderby s.StuName descending/asending select s;

5.维恩图工具:Enumerable类提供了一些扩展方法可以对两个或多个LINQ查询的数据进行合并(union)、比较(difference)交叉(intersection)
   a.Except(),返回包含两个容器的不同的结果集:

            List<string> myColor = new List<string> { "black", "red", "green" };
            List<string> yourColor = new List<string> { "black", "gray", "green" };

            var colorDiff = (from c in myColor select c).Except(from c in yourColor select c);
            Console.WriteLine("the difference :");
            foreach (string item in colorDiff)
            {
                Console.WriteLine(item);
            }

   b.Intersect():返回两个容器共同项


            var colorCommon = (from c in myColor select c).Intersect(from c in yourColor select c);

   c.Union():返回多个LINQ查询的所有成员,不包含重复项

            var colorAll = (from c in myColor select c).Union(from c in yourColor select c);

   d.Concat():返回多个LINQ查询的所有成员,包含重复项

            var colorAlls = (from c in myColor select c).Concat(from c in yourColor select c);

6.移除重复:Concat()方法返回的成员包含重复项,可以调用Distinct()方法去重

           foreach(string s in colorAlls.Distinct())  { Console.WriteLine(s);}

使用Enumerable类型和Lambda表达式来建立查询表达式(方法查询语法)

            string[] names = { "Rock", "Zed H", "Jason", "Mr H" };
            //方法查询语法,Enumerable类扩展方法参数为委托,此处使用Lambda表达式
            var name = names.Where(n => n.Contains(" ")).OrderBy(n => n).Select(n => n);
            foreach (var item in name)
            {
                Console.WriteLine(item);
            }

 


LINQ to XML

 

传统的XML API:通过使用System.Xml程序集中的类和方法来操作XML

 

        public static void BuildXmlDocWithDOM()
        {
            XmlDocument doc = new XmlDocument();  //在内存中新建一个Xml文档

 

            XmlElement School = doc.CreateElement("School");  //用元素<School>填充文档
   
            //创建一个<student>子元素,它包含一个Major特性
            XmlElement student = doc.CreateElement("Student");
            student.SetAttribute("Major", "IT");
           
            //创建<student>元素中的数据
            XmlElement name = doc.CreateElement("StuName");
            name.InnerText = "Rock";
            XmlElement number = doc.CreateElement("StuNo");
            number.InnerText = "007";
   
            //将<StuName> <StuNo>元素添加到<student>元素
            student.AppendChild(name);
            student.AppendChild(number);

 

            //将<student>元素添加到<School>元素
            School.AppendChild(student);

            //将完整的XML插入到XmlDocument对象并保存文件
            doc.AppendChild(School);
            doc.Save("school.xml");
        }


 
LINQ to XML :不必使用一组函数来更新XML树,只需要编写自上而下的代码就可以了(如下)

 

 

        public static void BuildXmlDocWithLINQ()
        {
            XDocument inventoryDoc = new XDocument(
                new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),  //XML文档公开声明
                    new XComment("Students Information!"),    //XML文档注释
                    new XElement("School",new XAttribute("Name","Tyut"), //每一个特定元素都可以有固有的特性元素
                       new XElement("Student", new XAttribute("Major", "IT"),
                         new XElement("StuName",new XAttribute("From","ChiFeng"), "Rock"),
                         new XElement("StuNo", "007"))
                       )
                  )
             );

             inventoryDoc.Save("newschool.xml");       

         }

            
 常用Linq成员及其意义:


  XAttribute                表示一个XML元素特性
  XCData                    表示XML文档中的CDATA部分
  XComment                  表示一个XML注释
  XDeclaration              表示一个XML文档的公开声明
  XDocument                 表示一个XML文档的全部内容
  XElement                  表示一个XML文档的特定元素包括根元素
  XName                     表示一个XML元素或XML特性的名称
  XNamespace                表示一个XML命名空间  

 

加载和解析XML内容:XElement和XDocument都支持Load()和Parse()方法,可以从包含XML数据的string对象或外部XML文件获取
                                    XML对象模型。

 

           string myElent =
                   @"<Car ID='3'>
                  <Color>Yellow</Color>
                  <Make>Yugo</Make>
                  </Car>";
            XElement newElement = XElement.Parse(myElent);  //获取string对象XML模型

            XDocument myDoc = XDocument.Load("Inventory.xml");  //获取外部XML模型
   
常用LINQ to XML的轴方法:

 

 Descendants<T>        返回经过筛选的元素集合,其中包含元集合中每个元素和文档的子元素
    
            string data = string.Empty;
            XDocument myDoc = XDocument.Load("newschool.xml");
            var makeInfo = from car in myDoc.Descendants("Student") //筛选<Student>元素节点下的所有子元素
                                     select car;
            foreach (var item in makeInfo)
            {
                data += string.Format("-->{0}\n", item);
            }
            Console.WriteLine(data); 

 

 

            输出结果如下:
           <Student Major="IT">
               <StuName From="ChiFeng">Rock</StuName>
               <StuNo>007</StuNo>
            </Student>
   
 Attributes()          返回源集合中经过筛选的每个元素的特性的集合
 
            var makeInfo = from stu in myDoc.Descendants("Student").Attributes()
                                     select stu;
         
Remove()             将源集合中的每个特性从其父节点中移除
 
            XDocument myDoc = XDocument.Load("newschool.xml");
            myDoc.Descendants("StuNo").Remove();
   
 Add()                  增加节点

 

            XElement newElement = new XElement("StuNo", "007");
            myDoc.Descendants("Student").First().Add(newElement)    //在Student元素下新增一个节点 
           
           
  
  
  
 

 

 

 

 

       

posted @ 2017-09-23 19:03  Zed_H  阅读(222)  评论(0)    收藏  举报