zoukankan      html  css  js  c++  java
  • C# Linq简介

    LInq是Language Integrated Query的简称,它是微软在.net framework 3.5里面新加入的特性,用以简化查询查询操作。它主要包含了3块,Linq to Object、Linq to SQL、Linq to XML,其中Linq to Object和对于对象的查询,Linq to XML则又提供了对XML格式数据的检索、设置等功能,其中值得关注的Linq to SQL是我们要重点掌握的,因为它改变了我们传统的对于SQL操作的认识。

    一、Linq to Object

    先上一段代码:

    string[] contries = new string[] { "china", "russia", "american", "spain", "japan", "china" };  
    var query = from c in contries select c;//Linq to object  
    IEnumerator enumerator = query.GetEnumerator();  
    while (enumerator.MoveNext())  
    {  
        Console.WriteLine(enumerator.Current);  
    }  
    

    注意Linq to Object的语法,from c in contries select c ; // 这里的c任意起名,in后面的contries 为数组对象或者是列表、集合等对象,select c 与前面的c保持一致。这是Linq强大的地方,试想我们以前要想查询数组里面的每一个元素要写一层for循环然后循环输出。这里似乎看不出什么明显优势的地方,我们继续往下看。

    var query = from c in contries select c;  
    替换为:  
    var query = from c in contries.Distinct() where c.Length == 5 orderby c ascending select c; 
    

    我们会发现利用linq可以很容易的像利用sql语句一样查询、排序,如果利用原始的技术可能要多些好几行代码!

    再举个例子。

    这是论坛某个坛友发的帖子,问如何用Linq进行分组查询。见linq分组统计

    我在里面给出了解答,当然了里面的List完全可以是从数据库中获取,我简单模拟了一下,代码如下。

    定义1个实体类:

    public class Product  
    {  
        public Product(string province, Int32 value)  
        {  
            this.Province = province;  
            this.Value = value;  
        }  
      
        public string Province { get; set; }  
        public Int32 Value { get; set; }  
    }  
    

    然后在Main函数中输入:

    var result = from p in list.AsEnumerable()  
                 group p by p.Province into g  
                 select new  
                 {  
                     g.Key,  
                     SumValue = g.Sum(p => p.Value)  
                 };  
    result.ToList().ForEach((i) =>  
    {  
        Console.WriteLine(i.Key + ":" + i.SumValue);  
    });  
    

    可以得到分组统计的结果。

    再附一个简单排序的例子。linq排序

    二、Linq to SQL

    这是Linq技术的重头戏,当然现在有了EntityFramework等技术,但是我们还是可以关注一下。

    我们新建两张表,很简单。

    然后在项目中新建一个Linq to SQL类,切换到设计界面。同时打开服务资源管理器,添加数据连接,连接到数据库。拖动classInfo和studentInfo两张表到Linq to SQL类文件的设计界面,我们会发现关系替我们都准备的好好的。

    OK,这时就可以写相应代码,进行添加操作了。

    DataClasses1DataContext datacontext = new DataClasses1DataContext();  
    classInfo classInfo = new classInfo()  
    {  
        classId = 1,  
        className = "grade1"  
    };  
    datacontext.classInfo.InsertOnSubmit(classInfo);  
      
    studentInfo studentInfo = new studentInfo()  
    {  
        studentId = "001",  
        studentName = "liming",  
        classId = 1  
    };  
      
    datacontext.studentInfo.InsertOnSubmit(studentInfo);  
      
    datacontext.SubmitChanges();  
    

    这样就添加了1条班级记录和1条学生记录。

    如果我们要删除一条学生记录怎么办?举个例子,键入如下代码:

    DataClasses1DataContext datacontext = new DataClasses1DataContext();  
    studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName == "liming");  
    datacontext.studentInfo.DeleteOnSubmit(studentInfo);  
    datacontext.SubmitChanges();  
    

    这样就把liming这个学生记录给删除了,很简单吧?

    好,现在我们修改这个学生记录,把名字改成zhang3。

    DataClasses1DataContext datacontext = new DataClasses1DataContext();  
    studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName == "liming");  
    studentInfo.studentName = "zhang3";//直接赋新的值  
    datacontext.SubmitChanges();//提交更改就可以了  
    

    补充一点很重要的,就是如何用linq to sql来进行查询操作。

    前面的Single其实就是一种查询操作,返回单个对象。

    直接上一个linq带条件的分页查询实例:

    DataClasses1DataContext datacontext = new DataClasses1DataContext();  
      
    var singleStudent = from s in datacontext.studentInfo  
                        where s.studentName != "zhang3"  
                        orderby s.classInfo descending  
                        select s;  
      
    IList<studentInfo> studentList = singleStudent.Skip(pageSize * (pageNumber - 1)).Take(pageSize).ToList();  
    foreach (studentInfo student in studentList)  
    {  
        Console.WriteLine("studentId:" + student.studentId + "studentName:" + student.studentName);  
    }  
    

    三、Linq to XML

    以前我们操作XML一般都用XmlDocument、XmlReader等核心类去处理,关于这个我在点击打开链接这个帖子中已经简单总结了一把。这里我们看看Linq是怎么处理XML的。

    1、创建XML

    XElement contacts =  
        new XElement("Students",  
        new XElement("Student",  
            new XElement("Name", "Xiao Ming"),  
            new XElement("Phone", "99599",  
            new XAttribute("Type", "Home")),  
            new XElement("phone", "010-99599",  
            new XAttribute("Type", "Work")),  
            new XElement("Address",  
                new XElement("Street", "123 Street"),  
                new XElement("City", "123 City"),  
                new XElement("State", "1"),  
                new XElement("Postal", "0000000")  
            )  
        )  
    );  
    contacts.Save("test.xml"); 
    

    你会发现,你只要记住XElement这一个核心类就可以使用Linq创建xml,而且编码的方式很轻松,就是在表达一个xml的层级关系。

    效果如下:

    <?xml version="1.0" encoding="utf-8"?>  
    <Students>  
      <Student>  
        <Name>Xiao Ming</Name>  
        <Phone Type="Home">99599</Phone>  
        <phone Type="Work">010-99599</phone>  
        <Address>  
          <Street>123 Street</Street>  
          <City>123 City</City>  
          <State>1</State>  
          <Postal>0000000</Postal>  
        </Address>  
      </Student>  
    </Students>  
    

    2、查询XML

    还是用上面生成的XML来做测试,键入如下代码:

    XElement root = XElement.Load("test.xml");  
    IEnumerable address = from el in root.Elements("Student").Elements("phone")  
                          where el.Attribute("Type").Value == "Work"  
                          select el;  
      
    foreach (XElement el in address)  
    {  
        Console.WriteLine(el.Value);  
    }  
    

    输出:010-99599。

    四、Linq to DataTable

    意思跟Linq to Object是一样的,应该属于Linq to Object的范畴,这里单独拿出来,分享一下。

    举个例子,对两个DataTable的数据进行合并,原贴见:两个DataTable合并列

    先构造两个DataTable。

    DataTable A = new DataTable();  
    A.Columns.Add("NameNumber", typeof(string));  
    A.Columns.Add("Type", typeof(string));  
      
    DataRow drA = null;  
    drA = A.NewRow();  
    drA["NameNumber"] = "111";  
    drA["Type"] = "Y";  
    A.Rows.Add(drA);  
      
    drA = A.NewRow();  
    drA["NameNumber"] = "222";  
    drA["Type"] = "N";  
    A.Rows.Add(drA);  
      
    DataTable B = new DataTable();  
    B.Columns.Add("NameNumber", typeof(string));  
    B.Columns.Add("Name", typeof(string));  
    B.Columns.Add("Address", typeof(string));  
      
    DataRow drB = null;  
    drB = B.NewRow();  
    drB["NameNumber"] = "111";  
    drB["Name"] = "张三";  
    drB["Address"] = "上海";  
    B.Rows.Add(drB);  
      
    drB = B.NewRow();  
    drB["NameNumber"] = "222";  
    drB["Name"] = "李四";  
    drB["Address"] = "北京";  
    B.Rows.Add(drB);  
    

    然后我们通过Linq to DataTable进行合并。

    var result = from p in A.AsEnumerable()  
                 from q in B.AsEnumerable()  
                 where p.Field<string>("NameNumber") == q.Field<string>("NameNumber")  
                 select new  
                 {  
                     NameNumber = p.Field<string>("NameNumber"),  
                     Type = p.Field<string>("Type"),  
                     Address = q.Field<string>("Address")  
                 };  
    result.ToList().ForEach(x => Console.WriteLine(x.NameNumber + "-" + x.Type + "-" + x.Address));  
    

    效果图下:

  • 相关阅读:
    Android 开发技术周报 Issue#276
    手动添加 Git bash 到鼠标右键
    Sublime Text3 3143 注册码
    MySQL主从复制
    Python-MongoDB的驱动安装、升级
    MongoDB数据库的安装、配置和使用
    js循环生成多个easyui datagrid数据网格时,初始化表格
    屏蔽掉Google Chrome 浏览器 textarea 单词拼写检测
    Fiddler屏蔽某些url的抓取方法
    解决VMware下安装Ubuntu 16.04 不支持1920X1080分辨率的问题
  • 原文地址:https://www.cnblogs.com/guwei4037/p/3499148.html
Copyright © 2011-2022 走看看