目录
什么是LINQ
从对象获取数据的方法一直都是作为程序的一部分而设计的,然而使用LINQ可以很轻松的查询对象集合
LINQ提供程序
匿名类型
匿名类型经常用于LINQ查询的结果之中
匿名类型的对象创建表达式:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Csharpzuoye
{
class Program
{
static void Main()
{
//必须使用var 匿名对象初始化语句
var student = new { Name = "Mary Jones", Age = 19, Major = "History" };
Console.WriteLine("{0},Age {1},Major:{2}", student.Name, student.Age, student.Major);
}
}
}
投影初始化语句
除了对象初始化语句的赋值形式,匿名类型的对象初始化语句还有两种允许的形式:简单标识符和成员访问表达式
如果编译器遇到了另一个具有相同的参数名,相同的推断类型和相同顺序的匿名类型,它会重用这个类型并直接创建新的实例,不会创建新的匿名类型
方法语法和查询语法
示例:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Csharpzuoye
{
class Program
{
static void Main()
{
int[] numbers = { 2, 5, 28, 31, 17, 16, 42 };
var numsQuery = from n in numbers //查询语法
where n < 20
select n;
var numsMethod = numbers.Where(x => x < 20); //方法语法
int numsCount = (from n in numbers //两种方法的组合
where n < 20
select n).Count();
foreach (var x in numsQuery)
Console.Write("{0} ", x);
Console.WriteLine();
foreach(var x in numsMethod)
Console.Write("{0} ", x);
Console.WriteLine();
Console.WriteLine(numsCount);
}
}
}
查询变量
LINQ 查询可以返回两种类型的结果--可以是一个枚举(可枚举的一组数据,不是枚举类型)它满足查询参数的项列表,也可以是一个叫做标量的的单一值,它满足查询条件的结果的某种摘要形式
查询表达式的结构
查询表达式有查询体后的from子句组成
from子句
from子句指定了数据源使用的数据集合,它还引入了迭代变量
join子句
联结的语法如下:
使用联结来结合两个或更多集合中的数据
联结操作接受两个集合然后创建一个临时的对象集合,每一个对象包含原始集合对象中的所有字段
什么是联结
LINQ 中的 join 接受两个集合然后创建一个新的集合,每一个元素包含两个原始集合中的原始成员
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Csharpzuoye
{
class Program
{
public class Student //声明类
{
public int StID;
public string LastName;
}
public class CourseStudent
{
public string CourseName;
public int StID;
}
static Student[] students = new Student[]
{
new Student{StID = 1,LastName = "Carson"},
new Student{StID = 2,LastName = "Klassen"},
new Student{StID = 3,LastName = "Fleming"},
};
//初始化数组
static CourseStudent[] studentsInCourses = new CourseStudent[]
{
new CourseStudent {CourseName = "Art",StID = 1},
new CourseStudent {CourseName = "Art",StID = 2},
new CourseStudent {CourseName = "History",StID = 1},
new CourseStudent {CourseName = "History",StID = 3},
new CourseStudent {CourseName = "Physics",StID = 3},
};
static void Main()
{
//查找所有选择了历史课的学生的姓氏
var query = from s in students
join c in studentsInCourses on s.StID equals c.StID
where c.CourseName == "History"
select s.LastName;
//显示所有选择了历史课的学生的名字
foreach (var q in query)
Console.WriteLine("Student taking History: {0}", q);
}
}
}
查询主体中的 from...let...where片段
from 子句
查询表达式从必需的from子句开始,后面跟的是查询主体。主体本身可以从任何数量的其他from子句开始,每一个from子句都指定了一个额外的源数
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Csharpzuoye
{
class Program
{
static void Main()
{
var groupA = new[] { 3, 4, 5, 6 };
var groupB = new[] { 6, 7, 8, 9 };
var someInts = from a in groupA //必需的第一个from
from b in groupB //查询主体的第一个子句
where a > 4 && b <= 8
select new { a, b, sum = a + b }; //匿名类型对象
foreach (var a in someInts)
Console.WriteLine(a);
}
}
}
据集合并引入了要在之后运算的迭代变量,所有from子句的语法和含义都是一样的
let 子句
let 子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符。let 子句的语法如下:
let Identifier = Expression
where 子句
where 子句根据之后的运算来去除不符合指定条件的项,语法如下:
where BooleanExpression
只要是在from...let...where部分中,查询表达式可以有任意多个where子句
一个项必须满足where 子句才能避免在之后被过滤
orderby 子句
orderby 子句接受一个表达式并根据表达式按顺序返回结果项
select....group子句
查询中的匿名类型
查询结果可以由原始集合中的项,项的某些字段或匿名类型组成
group子句
group 子句把 select 的对象根据一些标准进行分组
查询延续 :into
查询延续子句可以接受查询的一部分结果并赋予一个名字,从而可以在查询的另一部分中使用。