- A+
本文章是根据 微软MVP solenovex(杨旭)老师的视频教程编写而来,再加上自己的一些理解。
视频教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源码:https://github.com/hllive/LearnEFCore3.1
EFCore主要是通过Linq这个方式查询数据库
1、查询所有数据
把Leagues里的所有数据查询出来
第一种形式
通过Linq方法.ToList(),EFCore遇到ToList()语句就会执行SQL查询,如果不加过滤条件的话就是把表里的所有数据查询出来
第二种形式
通过Linq查询表达式,查询结果与Linq方法是一样的
[HttpGet] public IActionResult GetLeague() { //第一种形式 通过Linq方法 var leagues = _dbContext.Leagues.ToList(); //第二种形式 通过Linq查询表达式 var league2 = (from lg in _dbContext.Leagues select lg).ToList(); return Ok(leagues); }
不加过滤条件查询所有数据没有什么意义
需要加一些查询条件
,查询条件怎么加呢?
第一种写法
在后面加一个Where()方法,里面的参数是一个Lambda表达式
第二种写法
在后面加where语句,这与sql语句有点类似
[HttpGet] public IActionResult GetLeague() { //第一种 var leagues = _dbContext.Leagues .Where(l => l.Country == "中国")//查询条件 .ToList();//只有执行ToList()方法才真正执行数据库查询 //第二种 var league2 = (from lg in _dbContext.Leagues where lg.Country == "中国"//查询条件 select lg).ToList(); return Ok(leagues); }
通常在开发过程中都是使用第一种方法
延迟执行
在.ToList()方法之前都是返回IQueryable类型
IQueryable就是C#中Linq To SQL语句的返回类型,简单来说IQueryable就是可以叠加处理SQL语句,最后统一访问数据库,这个处理过程就叫
延迟执行
,这一步只是生成了SQL语句,并没有真正执行数据库查询
只有执行ToList()方法才真正执行数据库查询,这个ToList()方法之前都是可以多次叠加Where()方法
那么在什么情况下会执行数据库查询呢?
ToList()
、First()
、FirstOrDefault()
Single()
、SingleOrDefault()
、Last()
、LastOrDefault()
//Single只能是一个数据
Count()
、LongCount()
、Min()
、Max()
、Average()
、Sum()
Find()
、foreach()
还有异步版本:ToListAsync()
、FirstAsync()
First返回符合添加的第一条数据;First与FirstOrDefault的区别,First必须有数据,否则会报错,FirstOrDefault可有可无
foreach循环:遇到foreach语句EFCore会把数据库连接打开,然后连接一直处于开放状态,一直保持连接,直至foreach循环结束才关闭数据库连接,如果循环里执行比较耗时,可能就会出现一些异常或数据冲突,尽量不要这样写;应该先通过ToList(),然后对ToList的结果进行循环。
First()与FirstOrDefault()可以在方法参数里直接写Where查询条件
_dbContext.Leagues.FirstOrDefault(w => w.Country == "中国");
如果在代码中把查询条件写死了,生成的SQL语句也是写死的。如果把查询条件提取为变量,生成SQL语句就会使用参数类型
模糊查询
比如需要模糊sql查询条件
SELECT * FROM Leagues WHERE Country LIKE N'%中%'
//第一种 模糊查询 var leagues = _dbContext.Leagues .Where(l => l.Country.Contains("中"))//查询条件 .ToList(); //第二种 模糊查询 var league_ef = _dbContext.Leagues .Where(l => EF.Functions.Like(l.Country, "中%")) .ToList();
2、查询单个数据
[HttpGet] public IActionResult GetSingleLeague() { var _id = new Guid("4227506D-05E4-47A2-B94F-08D8451D5DC0"); //第一种 var leagues = _dbContext.Leagues.SingleOrDefault(l => l.Id == _id); //第二种 var league2 = _dbContext.Leagues.Find(_id); return Ok(new { leagues, league2 }); }
根据执行情况来看,请求得到两个相同的对象leagues和league2,但是只执行了一条SQL语句。
因为第一种查询的时候生成了查询SQL语句,查询出来的数据被context进行追踪,如果使用DbSet<>()上的Find()方法执行查询,如果context追踪内存中能找到这条数据,就不用进行数据库查询,直接从内存中读取数据返回
如果把【第一种】和【第二种】两种方法返过来查询就会执行两次数据库查询操作。
如果想使用
Last()
方法查询语句,必须排序操作:正序.OrderBy(x=>x.Id)
,倒序.OrderByDescending(x=>x.Id)
博客文章可以转载,但不可以声明为原创