本文章是根據 微軟MVP solenovex(楊旭)老師的視頻教程編寫而來,再加上自己的一些理解。
視頻教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源碼:https://github.com/hllive/LearnEFCore3.1
刪除數據
EFCore只能刪除被Context追蹤的數據,數據怎么能被追蹤呢,只能先查詢出來,然后操作刪除方法,刪除方法有四種,如代碼所示;調用Remove()或RemoveRange()方法后還沒有數據庫執行動作,只有調用_dbContext.SaveChanges()
才會執行數據庫事務操作並返回影響行數。
[HttpDelete]
public IActionResult DeleteLeague() {
//先查詢出來,因為只能刪除被追蹤的數據
var league = _dbContext.Leagues.SingleOrDefault(l => l.Country == "貴州");
if (league == null) return NotFound();
//1、單獨刪除方法
_dbContext.Leagues.Remove(league);//刪除單個Leagues
_dbContext.Remove(league);//直接在context上Remove()方法傳入model,它會判斷類型
//2、批量刪除方法
var league2 = _dbContext.Leagues.SingleOrDefault(l => l.Country == "中國");
_dbContext.Leagues.RemoveRange(league, league2);
_dbContext.RemoveRange(league, league2);
//執行數據庫操作
int count = _dbContext.SaveChanges();
return Ok(count);
}
修改數據
修改數據與刪除數據有點像,也是需要被Context追蹤的數據,然后才能進行修改,所追蹤的對象里有個狀態屬性,狀態設為Modify,調用SaveChanges()時才會執行相應的修改,修改某個字段后,context就知道某個字段已經被修改。
[HttpPut]
public IActionResult UpdateLeague() {
//先查詢出來,因為操作被追蹤的數據
var league = _dbContext.Leagues.FirstOrDefault();
//修改Name屬性,被追蹤的league狀態屬性就會變為Modify
league.Name += "-";
//執行數據庫操作
int count = _dbContext.SaveChanges();
return Ok(count);
}
根據執行結果可以看出,只修改了Name字段,這就是因為EFCore追蹤的數據,League類的name值改變了,所以才執行修改Name字段。
如果修改多條記錄,也就是修改集合數據,這時候EFCore就會生成集合數量的UPATE的SQL語句,如果有100條數據需要修改,EFCore就會生成100條UPATE的SQL語句。這種修改方法不太適合我們的業務場景。
在實際情況中,對象不一定是從數據庫中查詢出來的,而是由前端傳入的JSON數據。這時候就不能被EFCore追蹤,可以使用context.Update()方法進行數據追蹤
通過context查詢出來的數據都會被EFCore變化追蹤的,進行變化追蹤可能會消耗大類的內存或CPU處理,如果查詢量比較大,而且不需要變化追蹤,可以通過
AsNoTracking()
方法使對象不被EFcore追蹤,例如:_dbContext.Leagues.AsNoTracking().FirstOrDefault();
。在AsNoTracking()
后也需要執行First()或ToList()才會真正執行數據庫查詢。
[HttpPut("test")]
public IActionResult UpdateLeague2()
{
//var league = _dbContext.Leagues.AsNoTracking().FirstOrDefault();
//這里模擬前端傳過來的JSON數據序列化為對象
var league = new League {
Id = new Guid("EDAAEE79-78C9-43B5-A924-08D845203D11"),
Name= "貴州貴陽足球聯賽"
};
//修改對象的屬性
league.Name = league.Name.Replace("貴州貴陽", "遵義仁懷");
//讓context進行追蹤,並知道它已經被修改
_dbContext.Leagues.Update(league);
//執行數據庫操作
int count = _dbContext.SaveChanges();
return Ok(count);
}
這種離線的數據(沒有被追蹤)使用context.Update()方法執行時,EFCore不知道那些屬性或字段已經被修改那些沒有被修改。這種生成的SQL語句會把所有字段都重新賦值一遍,如果沒有賦值會被設置為NULL,如上圖執行結果,Country屬性本來沒有修改,執行SQL語句時被設置為NULL
如果只想修改某一個屬性的話也是可以做到的,以后再寫。。。
博客文章可以轉載,但不可以聲明為原創