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

先上一段代码:

1

2

3

4

5

6

7

string[] contries =new string[] {"china","russia","american","spain","japan","china" }; 

var query =from cin contriesselect 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循环然后循环输出。这里似乎看不出什么明显优势的地方,我们继续往下看。

1

2

3

var query =from cin contriesselect c; 

替换为: 

var query =from cin contries.Distinct()where c.Length == 5orderby cascending select c;

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

再举个例子。

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

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

定义1个实体类:

1

2

3

4

5

6

7

8

9

10

11

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函数中输入:

1

2

3

4

5

6

7

8

9

10

11

var result =from pin list.AsEnumerable() 

             group pby p.Provinceinto

             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,这时就可以写相应代码,进行添加操作了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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条学生记录。

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

1

2

3

4

DataClasses1DataContext datacontext =new DataClasses1DataContext(); 

studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName =="liming"); 

datacontext.studentInfo.DeleteOnSubmit(studentInfo); 

datacontext.SubmitChanges(); 

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

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

1

2

3

4

DataClasses1DataContext datacontext =new DataClasses1DataContext(); 

studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName =="liming"); 

studentInfo.studentName ="zhang3";//直接赋新的值 

datacontext.SubmitChanges();//提交更改就可以了 

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

DataClasses1DataContext datacontext =new DataClasses1DataContext(); 

   

var singleStudent =from sin datacontext.studentInfo 

                    where s.studentName !="zhang3" 

                    orderby s.classInfodescending 

                    select s; 

   

IList<studentInfo> studentList = singleStudent.Skip(pageSize * (pageNumber - 1)).Take(pageSize).ToList(); 

foreach (studentInfo studentin studentList) 

    Console.WriteLine("studentId:" + student.studentId +"studentName:" + student.studentName); 

三、Linq to XML

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

1、创建XML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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的层级关系。

效果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<?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来做测试,键入如下代码:

1

2

3

4

5

6

7

8

9

XElement root = XElement.Load("test.xml"); 

IEnumerable address =from elin root.Elements("Student").Elements("phone"

                      where el.Attribute("Type").Value =="Work" 

                      select el; 

   

foreach (XElement elin address) 

    Console.WriteLine(el.Value); 

输出:010-99599。

四、Linq to DataTable

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

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

先构造两个DataTable。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

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进行合并。

1

2

3

4

5

6

7

8

9

10

var result =from pin A.AsEnumerable() 

             from qin 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)); 

效果图下: