本文章是根據 微軟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)
博客文章可以轉載,但不可以聲明為原創