5、Entity Framework Core 3.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语句就会使用参数类型

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

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

posted @ 2020-08-26 21:00  hllive  阅读(1189)  评论(0编辑  收藏  举报