.NET 云原生架構(gòu)師訓(xùn)練營(模塊二 基礎(chǔ)鞏固 EF Core 更新和遷移)--學(xué)習(xí)筆記
2.4.6 EF Core -- 更新
狀態(tài)
自動變更檢測
不查詢刪除和更新
并發(fā)
狀態(tài)
Entity State
Property State
Entity State
Added 添加
Unchanged 沒有變化
Modified 已修改
Deleted 已刪除
Detached 未跟蹤

Property State
IsModified
CurrentValue
OriginValue
自動變更檢測
使用自動變更檢測完成確定字段的更新
使用自動變更檢測完成任意字段的更新
使用自動變更檢測完成確定字段的更新
ProjectController
[HttpPatch]
[Route("{id}")]
public async Task> SetTitleAsync(string id, [FromQuery] string title, CancellationToken cancellationToken)
{
// 查詢實體信息
var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
// 修改實體屬性
origin.Title = title;
// 數(shù)據(jù)提交保存
await _lighterDbContext.SaveChangesAsync();
return origin;
}
修改分組信息
// 查詢實體信息
var originGroup = await _lighterDbContext.ProjectGroups.Where(g => g.ProjectId == id).ToListAsync(cancellationToken: cancellationToken);
// 修改實體屬性
foreach (var group in originGroup)
{
group.Name = $"{title} - {group.Name}";
}
查詢項目信息時帶出分組信息
[HttpGet]
public async Task> GetListAsync(CancellationToken cancellationToken)
{
return await _lighterDbContext.Projects.Include(p => p.Groups).ToListAsync(cancellationToken);
}
使用自動變更檢測完成任意字段的更新
[HttpPatch]
[Route("{id}")]
public async Task> SetAsync(string id, CancellationToken cancellationToken)
{
// 查詢實體信息
var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
var properties = _lighterDbContext.Entry(origin).Properties.ToList();
// 修改實體屬性
foreach (var query in HttpContext.Request.Query)
{
var property = properties.FirstOrDefault(p => p.Metadata.Name == query.Key);
if (property == null)
continue;
var currentValue = Convert.ChangeType(query.Value.First(), property.Metadata.ClrType);
_lighterDbContext.Entry(origin).Property(query.Key).CurrentValue = currentValue;
_lighterDbContext.Entry(origin).Property(query.Key).IsModified = true;
}
// 數(shù)據(jù)提交保存
await _lighterDbContext.SaveChangesAsync(cancellationToken);
return origin;
}
不查詢刪除和更新
刪除之前先查詢
var id = 1;
using(var db = new entityContext())
{
var entity = db.dbset.FirstOrDefault(e=>e.ID == id);
if(entity != null)
{
db.dbset.Remove(entity);
db.SaveChanges();
}
}
不查詢刪除
var id = 1;
using(var db = new entityContext())
{
var entity = new Entity{ID = id};
db.dbset.Attach(entity);
db.dbset.Remove(entity);
db.SaveChanges();
}
不查詢更新
try
{
using(var db = new dbContext())
{
var entity = new myEntity{PageID = pageid};
db.Pages.Attach(entity);// added
entity.Title = "new title";// modified, isModified=true
entity.Url = "new-url";
db.SaveChanges();
}
}
catch(DataException)
{
}
并發(fā)
樂觀處理:系統(tǒng)認(rèn)為數(shù)據(jù)的更新在大多數(shù)情況下是不會產(chǎn)生沖突的,只在數(shù)據(jù)庫更新操作提交的時候才對數(shù)據(jù)作沖突檢測(推薦)
悲觀處理:根據(jù)命名即對數(shù)據(jù)庫進(jìn)行操作更新時,對操作持悲觀保守的態(tài)度,認(rèn)為產(chǎn)生數(shù)據(jù)沖突的可能性很大,需要先對請求的數(shù)據(jù)加鎖再進(jìn)行相關(guān)操作
在 Entity 中添加行版本號字段
///
/// 行版本號
///
[Timestamp]
public byte[] RowVersion { get; set; }
每次對數(shù)據(jù)進(jìn)行更新的時候,都會產(chǎn)生最新的版本號,如果更新的時候查詢的版本號與之前的版本號不一致,就會報錯
在 UpdateAsync 方法中的查詢和更新中間如果數(shù)據(jù)庫的行版本號發(fā)生了修改,就會報錯
ProjectController
[HttpPut]
[Route("{id")]
public async Task> UpdateAsync(string id, [FromBody] Project project, CancellationToken cancellationToken)
{
var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
if (origin == null)
return NotFound();
_lighterDbContext.Entry(origin).CurrentValues.SetValues(project);
await _lighterDbContext.SaveChangesAsync(cancellationToken);
return origin;
}
通過客戶端傳入行版本號,解決前端瀏覽器數(shù)據(jù)覆蓋問題
_lighterDbContext.Entry(origin).Property(p => p.RowVersion).OriginalValue = project.RowVersion;
2.4.7 EF Core -- 遷移
生成 SQL 腳本
從空白開始生成sql腳本
dotnet ef migrations script
生成指定版本到最新版本的sql
dotnet ef migrations script AddNewTables
從A-B版本生成遷移SQL腳本
dotnet ef migrations script AddNewTables AddAuditTable
2.4.8 EF Core -- 其他
database-first
dotnet ef dbcontext scaffold "server=172.0.0.1;port=7306;user=root;password=root123456@;database=lighter" Pomelo.EntityFrameworkCore.MySql -o Models
GitHub源碼鏈接:
https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi
課程鏈接
.NET云原生架構(gòu)師訓(xùn)練營講什么,怎么講,講多久
