上回說到 FreeSql.DbContext 的規則,以及示範它的執行過程,可惜當時還不支援“樂觀鎖”,對于更新資料來講并不安全。
FreeSql 核心庫 v0.3.27 已提供樂觀鎖支援。
實作原理
樂觀鎖的原理,是利用實體某字段,如:long version,更新前先查詢資料,此時 version 為 1,更新時産生的 SQL 會附加 where version = 1,當修改失敗時(即 Affrows == 0)抛出異常。
每個實體隻支援一個樂觀鎖,在屬性前标記特性:[Column(IsVersion = true)] 即可。
無論是使用 FreeSql/FreeSql.Repository/FreeSql.DbContext,每次更新 version 的值都會增加 1
至此,FreeSql.DbContext 的更新操作就安全了。
安裝
dotnet add package FreeSql.DbContext
測試功能
下面示範更新 BigNumber 屬性,為什麼定義他為 string 呢,對于數字的更新 set clicks = clicks + 1,是安全的操作。
BigInteger 了解嗎,我們就當 BigNumber 是一個超大的數字吧,普通數字無法表示的。
var fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
.UseAutoSyncStructure(true)
.UseLazyLoading(true)
.UseNoneCommandParameter(true)
.UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
.Build();
public class Song {
[Column(IsIdentity = true)]
public int Id { get; set; }
public string BigNumber { get; set; }
[Column(IsVersion = true)]//使用簡單
public long versionRow { get; set; }
}
public class SongContext : DbContext {
public DbSet<Song> Songs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder) {
builder.UseFreeSql(fsql);
}
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuETN4kTO2IjMxETL0QTN0EzMyIjM5IzMwkTMwITL3ADNxMzLcNDM5EDMy8CX3ADNxMzLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
當更新時,版本不正确提示以下錯誤,DbContext 将復原操作:
總結
FreeSql.DbContext 實作類似 EFCore 使用方法,跟蹤對象狀态,最終通過 SaveChanges 方法送出事務。
目前是第二個初版,已實作狀态跟蹤儲存(導航屬性的跟蹤暫時不支援)。
配合樂觀鎖這個殺手锏,FreeSql 越來越有 ORM 的影子了。
github: https://github.com/2881099/FreeSql(求星星,謝謝)