前言
提醒:为了能够将知识点学得更加透彻、记得更加牢固 我会通过教学讲解的方式把知识写下来 因为在过程中会让人从学生变成老师 这个过程会挖掘出新的知识和观点 是一个自我思维切换而达成的知识深度挖掘和提升的过程 如果能帮助到大家那就最好 如果有讲错的地方还请多多指教!我只是一只菜鸡 感谢理解!
1、初识LINQ
相信大家多多少少都在网上或者书里看到过LINQ这玩意,那它到底是个什么玩意呢?今天就和大家一起来学习下LINQ
LINQ是集成到C#和VB .NET这些语言中用于提供查询数据能力的一个新特征
在关系型数据库中,数据被组织放入规范性很好的表中,并且通过简单而又强大的语言SQL来进行访问,然而程序中却与数据库相反,保存在类对象或结构中的数据差异很大,因此没有通用的查询语句来从数据结构中获取数据,自C#3.0引入LINQ后,我们便有了查询对象数据的能力
就是说LINQ是C#提供给了我们开发者一个快速查询数据的能力
LINQ-----------让语言更优美,让查询更便捷,让代码更出色。
2、简单的LINQ案例
先来一个示例,让大伙看看LINQ的魅力所在
要使用LINQ的话就要引用它所在的命名空间 using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class GameText
{
public int gameID; //游戏ID
public string gameName; //游戏名称
public string gameIntduced; //游戏介绍
public int gameSize; //游戏大小
}
class Program
{
static List game = new List()
{
new GameText(){gameID = 1,gameName = "东凑西凑",gameIntduced = "这是一个2D实习面试项目",gameSize = 1},
new GameText(){gameID = 2,gameName = "同桌的你",gameIntduced = "这是一个青春校园题材的游戏",gameSize = 5},
};
static void Main(string[] args)
{
var res = from m in game
where m.gameID > 1
select m.gameName;
foreach (var item in res)
{
Console.WriteLine(item);
}
}
}
}
主要看这个地方
var res = from m in game
where m.gameID > 1
select m.gameName;
from in 都是关键字 game是我们要查询的数据的对象 m表示game里面的元素
where 是用来做条件限制的 这里我写了一个m.gameID > 1的条件 意思就是查询game集合中的gameID大于1的元素
select m.gameName 查出满足条件的游戏并返回它的游戏名称
我们来看下输出结果
东凑西凑游戏ID为1 同座的你ID为2
where m.gameID > 1
显然是同座的你这款游戏符合条件 所以最后我们得到的是同座的你这款游戏
看吧是不是很简单,自己动手敲一下马上就能理解了!
3、关于LINQ的不同语法
刚刚的案例讲的是LINQ表达式的写法也称(查询语法),这里我们还可以使用方法语法来进行数据查询
查询语法(query syntax)是声明形式的,看上去和SQL语句很相似。查询语法使用查询表达式形式书写。
方法语句(method syntax)是命令形式的,它使用的是标准的方法调用。方法是一组叫做标准查询运算符的方法
只要我们引用了System.Linq; 我们就可以调用Where方法
System.Linq命名空间下有一个Enumerable类
Enumerable类为我们开发者提供了超多扩展方法和共享方法,这里面水应该挺深了没怎么研究跳过,我们直接操作集合然后.调用里面的where方法就好了
它需要我们传入一个Func委托 这里有两种写法
一种是用Lambda表达式来做,另一种就是比较麻烦的单独写一个方法
先来麻烦的、其实也简单Where就是做过滤用的,内部会让集合每个元素都调用我们传进行的方法 所以我们要写一个参数为GameText、返回值为bool的方法传到where中
//var res = from m in game
// where m.gameID > 1
// select m.gameName;
var res = game.Where(whereFunc);
foreach (var item in res)
{
Console.WriteLine(item.gameName.ToString());
}
static bool whereFunc(GameText t)
{
if (t.gameID > 1) return true;
return false;
}
启动程序 输出也是 同座的你 没毛病老铁
嗯的确也就几步 不算太麻烦,但是Lambda表达式能让它更加简单化
//var res = from m in game
// where m.gameID > 1
// select m.gameName;
//var res = game.Where(whereFunc);
var res = game.Where(g => g.gameID > 1);
foreach (var item in res)
{
Console.WriteLine(item.gameName.ToString());
}
//static bool whereFunc(GameText t)
//{
// if (t.gameID > 1) return true;
// return false;
//}
还是输出了同座的你 没毛病!
4、LINQ多表查询操作
要进行多表操作我们就要学习联结查询,学过SQL的同学应该对联结并不陌生,恰好我只是稍微碰过SQL一下,头一回学联结这个知识点,那它到底是个什么玩意呢?
联结查询接受两个集合然后创建一个临时的对象集合,要想进行联结操作那就必须每个源对象中需要共享某个可以进行比较,以判断是否相等的值才可以进行联结
直接上示例 一看示例就懂了
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Gamer
{
public int id;
public string playName;
}
class GameText
{
public string gameName;
public int id;
}
class Program
{
static List game = new List()
{
new Gamer(){id = 0,playName = "小红"},
new Gamer(){id = 1,playName = "小黑"},
new Gamer(){id = 2,playName = "小蓝"},
new Gamer(){id = 3,playName = "小黄"},
new Gamer(){id = 4,playName = "小小"},
};
static List game2 = new List()
{
new GameText(){gameName = "东凑西凑",id = 1},
new GameText(){gameName = "东凑西凑",id = 4},
new GameText(){gameName = "同座的你",id = 0},
new GameText(){gameName = "同座的你",id = 2},
new GameText(){gameName = "同座的你",id = 3},
};
}
}
现在我们有两个类
Gamer存储的是玩家的ID和名字
GameText存储的是游戏的名字和游玩此游戏玩家的ID
现在我们单纯查game表只能得到玩家的名字和ID并不能查到这个玩家玩的是哪一款游戏,这个时候我们就可以用到LINQ里的联结操作(join子句)
static void Main(string[] args)
{
var res = from g in game
join g2 in game2 on g.id equals g2.id
where g2.gameName == "同座的你"
select new { playerName = g.playName, gameName = g2.gameName }; //匿名类型对象
//var res = game.Where(g => g.gameID > 1);
foreach (var item in res)
{
Console.WriteLine(item);
}
}
前面几个关键字都解释过了 这里就讲讲join的操作
join g2 in game2 这句话完全的意思和 from g in game 一样的
(这里要注意查询表达式必须从from子句开始)
from 后面跟的是要做查询的对象
join 后面跟的是要联结的对象(表示要和那个集合做联结)
on 后面是联结条件
如果g.id 和 g2.id 相等 就判断下面的条件where g2.gameName == "同座的你"
**Gamer存储的是玩家的ID和名字
GameText存储的是游戏的名字和游玩此游戏玩家的ID**
他们的ID相同并且玩的是同座的你这款游戏那就满足了查询条件
回去看回我们的那个表 是不是 小红 小蓝 小黄 这三个人玩的是同座的你这款游戏
嗯输出的结果 没毛病
这里好像还有一种叫联合查询,我没有搞懂他们两个之间的关系,感觉本质上是一样的也是可以进行多表查询操作,坐等哪位老哥教教弟弟!
这里我也把联合查询的写出来 其他东西都不需要变
static void Main(string[] args)
{
var res = from g in game
from g2 in game2
where g.id == g2.id && g2.gameName == "东凑西凑"
select new { playerName = g.playName, gameName = g2.gameName };
foreach (var item in res)
{
Console.WriteLine(item);
}
}
不多解释了 应该不难理解吧。
5、LINQ对查询结果做排序操作
这里介绍orderby子句
orderby子句接受一个表达式并根据表达式一次返回结果项
orderby子句默认排序是升序,我们也可以通过ascending和descending关键字显式设置元素的排序为升序还是降序
一起来看看示例
就加了一句orderby g.id descending 其他代码不变
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Gamer
{
public int id;
public string playName;
}
class GameText
{
public string gameName;
public int id;
}
class Program
{
static List game = new List()
{
new Gamer(){id = 0,playName = "小红"},
new Gamer(){id = 1,playName = "小黑"},
new Gamer(){id = 2,playName = "小蓝"},
new Gamer(){id = 3,playName = "小黄"},
new Gamer(){id = 4,playName = "小小"},
};
static List game2 = new List()
{
new GameText(){gameName = "东凑西凑",id = 1},
new GameText(){gameName = "东凑西凑",id = 4},
new GameText(){gameName = "同座的你",id = 0},
new GameText(){gameName = "同座的你",id = 2},
new GameText(){gameName = "同座的你",id = 3},
};
static void Main(string[] args)
{
var res = from g in game
join g2 in game2 on g.id equals g2.id
where g2.gameName == "同座的你"
orderby g.id descending
select new { playerName = g.playName, gameName = g2.gameName };
foreach (var item in res)
{
Console.WriteLine(item);
}
}
}
}
因为默认我们ID就是0 1 2 3.. 升序的 所以我们把数据倒序来看看效果
升序状态下应该输出的是 小红小蓝小黄
我们用orderby g.id descending 按 g.id来倒序输出结果
所以输出了小黄 小蓝 小红