5、Entity Framework Core 3.1入门教程-查询数据

  • A+
所属分类:.NET技术
摘要

本文章是根据 微软MVP solenovex(杨旭)老师的视频教程编写而来,再加上自己的一些理解。
视频教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源码:https://github.com/hllive/LearnEFCore3.1


本文章是根据 微软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语句就会使用参数类型
5、Entity Framework Core 3.1入门教程-查询数据
5、Entity Framework Core 3.1入门教程-查询数据

模糊查询
比如需要模糊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 }); } 

5、Entity Framework Core 3.1入门教程-查询数据
5、Entity Framework Core 3.1入门教程-查询数据
根据执行情况来看,请求得到两个相同的对象leagues和league2,但是只执行了一条SQL语句。
因为第一种查询的时候生成了查询SQL语句,查询出来的数据被context进行追踪,如果使用DbSet<>()上的Find()方法执行查询,如果context追踪内存中能找到这条数据,就不用进行数据库查询,直接从内存中读取数据返回

如果把【第一种】和【第二种】两种方法返过来查询就会执行两次数据库查询操作。

如果想使用Last()方法查询语句,必须排序操作:正序.OrderBy(x=>x.Id),倒序.OrderByDescending(x=>x.Id)

博客文章可以转载,但不可以声明为原创