一、什么是Linq
1.Linq也叫“查询表达式”,是将查询功能直接集成到C#语言种的一种技术。
2.Linq提供以下数据源的查询功能
1)对象集合(支持IEnumberable或IEnumberable
2)SQL数据库
3)Xml文档
4)ADO.NET数据库
5)Web服务
/*
学习查询表达式Linq
支持的查询环境
1:对象集合
*/
class Demo{
public void Test1(){
//对象集合(支持IEnumberable或IEnumberable的)
List liObj=new List();
Dictionary dic=new Dictionary();
ArrayList al=new ArrayList();
Hashtable ht=new Hashable();
}
static void Main(string[] args){
}
}
二、一般查询
1)var关键字是3.5新推出的一个定义变量的类型
作用:一种弱化类型的定义,可以代替任何类型编译器。可以根据上下文来判断你到底想用什么类型。
class Demo{
public void Text1(){
//var弱数据类型
var str1="你好";
var num1=200;
Console.WriteLine(str1);
Console.WriteLine(num1);
}
static void Main(string[] args){
Demo obj=new Demo();
obj.Text1();
}
}
2)编写雇员、雇员级别实体类
//雇员实体类
public class Employee{
public int ID{set;private get;} //编号
public string Name{set;private get;} //姓名
public int Age{get;private set;} //年龄
public int LeveNum{get;private set} //级别
public Employee(int id,string name,int age,int level){
ID=id;
Name=name;
Age=age;
LevelNum=level;
}
public override string ToString(){
return string.Format("ID={0},Name={1},Age={2},LeveNum={3}",ID,Name,Age,LeveNUm);
}
}
//实体类雇员的级别
public class EmpLevel{
public int ID{get,private set;} //编号
public int LevelNum{get;private set;} //级别编号
public string LevelName{get;private set;} //级别名称
public float Salary{get; private set;} //级别的工资
public EmpLevel(int id,int levelNum,string levelName,float salary){
ID=id;
LevelNum=levelNum;
LevelName=levelName;
Salary=salary;
}
public override string ToString(){
return string.Format("ID={0},LevelNum={1},LevelName={2},Salary={3}",ID,LevelNum,LevelName,Salary)
}
}
3)编写查询类
//数据集合查询
using Syetem;
using Syetem.Collection.Generic;
using Syetem.Linq; //Linq查询的命名空间
using Syetem.Text;
using Syetem.Therading.Tasks;
public class Demo{
List empArray; //雇员信息
List empLeArray; //雇员级别
List empQueryResult; //查询结果
public Demo(){
empArray=new List();
empLeArray=new List();
empQueryResult=new List();
//集合信息,初始化信息(雇员信息)
empArray.Add(new Employee(1,"张三",40,4));
empArray.Add(new Employee(2,"李四",11,3));
empArray.Add(new Employee(3,"王五",22,2));
empArray.Add(new Employee(4,"张超",33,1));
empArray.Add(new Employee(5,"马汉",44,2));
empArray.Add(new Employee(6,"陈龙",55,3));
empArray.Add(new Employee(7,"赵虎",66,4));
//集合信息,初始化信息(雇员级别信息)
empLeArray.Add(new EmpLevel(1,1,"一级技术员",5000F));
empLeArray.Add(new EmpLevel(2,2,"二级工程师",6500F));
empLeArray.Add(new EmpLevel(3,3,"三级高工",8000F));
empLeArray.Add(new EmpLevel(4,4,"四级专家",9500F));
}
//传统查询,查询level级别大于2的所有公司雇员
public void Test1(){
//遍历结果
foreach(Employee emp in empArray){
if(emp.LevelNum>2){
empQueryResult.Add(emp);
}
}
//显示符合要求的查询结果
foreach(Employee emp empQueryResult{
Console.WriteLin(emp.ToString());
}
}
//Linq查询,查询level级别大于2的所有公司雇员
public void Test2(){
var result=from m in empArray //筛选取自哪些内容
where m.LevelNum>2 && m.Age>40 //筛选条件
select m.Name; //筛选结果
//显示查询结果
foreach(var item in result){
Console.WriteLine(item);
}
}
//使用Linq的扩展方法,查询Level大于2的所有雇员信息
public void Test3(){
//使用扩展方法1
var result1=empArray.Where(FilterConditionMethod);
//显示结果
foreach(var item in result1){
Console.WriteLine(item);
}
//使用拓展方法2
var result2=empArray.Where(e=>e.LevelNum>2);
//显示结果
foreach(var item in result2){
Console.WriteLine(item);
}
}
//Linq扩展方法1过滤条件方法
public bool FilterConditionMethod(Employee emp){
if(emp.LevelNum>2){
return true;
}else{
return false;
}
}
static void Main(string[] args){
Demo obj=new Demo();
obj.Test1();
obj.Test2();
obj.Test3();
}
}
4)C#扩展方法
目的:为一个现有类型添加一个方法,现有类型既可以是int,string等数据类型,也可以是自定义的数据类型。
重要性质:1.只有静态类才可以添加拓展方法。2.拓展方法必须是静态且必须有三个参数:this,要拓展的类型,对象名称。3.调用拓展方法,必须用对象来调用。
//C#拓展方法,
public class Demo{
//...实体类可粘贴上面定义过的
public static void Test1(){
string str="同学们"; //string运行时默认为String类
string result=str.TestMethod(); //原本并没有这个方法,会报错
Console.WriteLine("Sting扩展方法结果"+result);
//第二个int拓展方法
int num=88; //int运行时默认为Int32类
int intresult=num.TestMethodNumber();
int intresult1=num.TestMethodNumber(2000);
Console.WriteLine("Int32扩展方法结果1"+intresult);
Console.WriteLine("Int32扩展方法结果2"+intresult1);
}
//第一种int拓展方法
public static string TestMethod(this string name){
return name+"大家好";
}
//第二种int拓展方法
public static int TestMethodNumber(this int name){
return name+1000;
}
//第三种int拓展方法带参数
public static int TestMethodNumber(this int name,int para){
return name+para;
}
static void Main(string[] args){
Test1();
}
}
三、联合查询
联合查询的所有集合中应当有共同字段
/*
Linq联合查询
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Therading.Tasks;
public class Demo{
//...实体类可粘贴上面定义过的
//学习Linq查询,查询出两个集合的并集
public void Test(){
var queryResult=from e in empArray
from l in empLeArray
select new{e,l};//输出两个集合的并集,很少能用到
//显示结果
foreach(var item in queryResult){
Console.WriteLine(item.ToStringh())
}
//输出所有大于三级的高工雇员信息
var queryResult1=from e in empArray
from l in empLeArray
where e.LevelNum==l.LevelNum && e.LevelNum>3
select new{e,l};
foreach(var item in queryResult1){
Console.WriteLine(item.ToStringh())
}
//查询三级以上所有的高工雇员姓名、级别名称、工资
var queryResult2=from e in empArray
from l in empLeArray
where e.LevelNum==l.LevelNum && e.LevelNum>3
select new{e.Name,l.LevelName,l.Salary};
foreach(var item in queryResult2){
Console.WriteLine(item.ToStringh())
}
}
static void Main(string[] args){
Demo obj=new Demo();
obj.Test();
}
}
四、查询结果排序
/*
Linq查询结果排序
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Therading.Tasks;
public class Demo{
//...实体类可粘贴上面定义过的
//查询一级以上所有员工雇员姓名、级别名称、工资,且以级别、姓名、年龄进行输出结果排序
public void Test(){
var queryResult2=from e in empArray
from l in empLeArray
where e.LevelNum==l.LevelNum && e.LevelNum>1
orderby e.LevelNum,e.Name,e.Age descending //加上descending为降序,不加正序
select new{e.Name,l.LevelName,l.Salary};
foreach(var item in queryResult2){
Console.WriteLine(item.ToStringh());
}
}
static void Main(string[] args){
Demo obj=new Demo();
obj.Test();
}
}
五、Join on与分组查询以及Any与All关键字
/*
Linq之Join on与分组查询以及Any与All关键字
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Therading.Tasks;
public class Demo{
//...实体类可粘贴上面定义过的
public void Test(){
//使用Join on做联合查询
from queryResult=from e in empArray
join l in empLeArray
on e.LevelNum equals l.LevelNum //连接条件
where e.LevelNum>2 && l.Salary>8000
select new{e,l};
foreach(var item in queryResult){
Console.WriteLine(item.e.Name,item.l.LevelName);
}
//使用group by做分组查询
//对雇员信息集合,按照级别进行分组查询,查询统计每个级别的人员数量
var queryResult1=from e in empArray
group e by e.LevelNum into g
select new{g.Key,counts=g.Count()};//Key 分组关键字
//查询结果
foreach(var item in queryResult1){
Console.WriteLine(item.Key,item.Count());
}
//使用量词操作符“any”,“all”:判断集合中是否满足某个条件
//Any表示是否至少有一个满足查询条件
//查询雇员信息集合中,是由有一个叫“张三”员工
bool boolResult=empArray.Any(m==>m.Name="张三");
Console.WriteLine("集合中是否有一个是张三:"+boolResult);
//All表示必须都满足查询条件
//查询雇员信息集合中,是否所有员工都叫“张三”
bool boolResult=empArray.All(m==>m.Name="张三");
Console.WriteLine("集合中是否都是是张三:"+boolResult);
static void Main(string[] args){
Demo obj=new Demo();
obj.Test();
}
}