c# linq


LINQ(读音link)代表语言集成查询(Language Integrated Query),是.NEt框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合,使用它,你可以从数据库、程序对象的集合以及XML文档中查询数据

Linq语法
let子句

let子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符,它是from...let...where片段中的一部分

?
1 2 3 4 5 var query = from a in groupA    from b in groupB    let sum = a + b    where sum < 12    select new(a,b,sum);
 from子句  

from子句指定了要作为数据源使用的数据集合,它的语法是:

?
1 from Type Item in Items

其中Type是集合中元素的类型,是可选的,因为编译器可以从集合来推断类型。  Item是迭代变量的名字。  Items是要查询的集合的名字,必须是可枚举类型的

它和foreach比较相似,但foreach语句在遇到代码时就执行其主体,二from子句什么也不执行。它创建可以执行的后台代码对象,只有在程序的控制流遇到访问查询变量的语句时才会执行

 join子句  

如果您对SQL中的join比较熟悉的话,那么LINQ中的join对你来说也不是什么难事,不熟悉的话,,当我没说。

我们可以使用join来结合两个或更多集合中的数据,它接受两个集合然后创建一个临时的对象集合

?
1 2 var query = from s in students   join c in course on s.SID equals c.SID

equals用于比较相等性的字段,不能使用“==”代替,下面示例中有三个学生和三门课程,我们要做的是查找选修了历史课的学生名

?
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;   namespace LINK查询 {  class Program  {  public class Student //声明student类  {   public int stId; //学生ID   public string stuName; //学生姓名  }    public class Course //声明course类  {   public int stId; //学生ID   public string courseName; //课程名  }    static Student[] students = new Student[]  {   new Student {stId = 1,stuName = "jack"},   new Student {stId = 2,stuName = "taylor"},   new Student {stId = 3,stuName = "fleming"}  };    static Course[] courses = new Course[]  {   new Course{stId = 1,courseName = "art"},   new Course{stId = 2, courseName = "art"},   new Course{stId = 1,courseName = "history"},   new Course{stId = 3, courseName = "history"},   new Course{stId = 3,courseName = "physics"},  };    static void Main(string[] args)  {   //查询所有选修了history课的学生名   var query = from s in students    join c in courses on s.stId equals c.stId    where c.courseName == "history"    select s.stuName;     foreach(string str in query)   {   Console.Write("{0} ", str);   }   Console.ReadKey();  }  } }

输出 jack fleming

讲解一下查询过程:它会依次使用student中的对象与course中的所有对象进行对比,查找是否符合 s.stId equals c.stId where c.courseName == "history" 要求。

stID stuName
1 jack
2 taylor
3 fleming

 stID  courseName
 1  art
 2  art
 1  history
 3  history
 3  physics

即先将(1,jack)和(1,art),(2,art)...(3,physics)分别匹配,然后再(2,taylor)和(1,art),(2,art)...(3,physics),直到所有都匹配完,最终可以找到两条可以匹配的结果

 where子句  

where子句根据之后的运算来除去不符合要求的项,一个查询表达式可以有任意多个where子句,一个项必须满足所有的where条件才能避免被过滤,其语法为

?
1 2 where BoolenExpression1 where BoolenExpression2

前面的例子已经多次用过where,这里就不举例了

 orderby子句  

orderby可以很方便的将返回的数据进行排序,可选ascending和descending两种方式,默认的是ascending

语法: orderby Expression ascending or descending 二选一

为join子句中的例子增加一个orderby子句,返回结果就变成了 fleming jack

?
1 2 3 4 5 var query = from s in students       join c in courses on s.stId equals c.stId       where c.courseName == "history"                orderby s.stuName  //排序       select s.stuName;
 group子句  

group子句可以让你把select的结果按指定的键(key)进行分组 ,每一个分组由一个叫做键的字段区分,分组本身是可枚举类型的并且可以枚举它的项

?
1 2 3 4 5 6 7 8 9 10 11 var query = from student in students    group student by student.major;      foreach (var s in query)    {     Console.WriteLine("{0}", s.key);     foreach (var t in s)     {      console.writeLine(" {0}", t.Name);     }    }
 select子句  

select子句指定所选定的对象哪部分应该被选择。可以指定下面的任意一项

a: 整个数据项

b: 数据项的一个字段

c: 数据项中几个字段组成的新对象(或类似其他值)

?
1 2 3 4 5 6 7 8 9 10 11 var query = from s in students       select s; //整个数据项      var query = from s in students       select s.stuName; //s中的一个字段      var query = from a in groupA       from b in groupB       let sum = a + b       where sum < 12       select new (a, b, sum);  //a,b,sum组成的新字段
 查询延续: into子句  

查询延续子句可以接受查询的一部分结构并赋予一个名字,从而可以在查询的另一部分中使用

?
1 2 3 4 5 var someInt = from a in groupA     from b in groupB     into groupAandB     from c in groupAandB     select c;
   
   
   
   
   
   
   
   
   
   
   
       

end