efcore 新特性 SaveChanges Events
efcore 新特性 SaveChanges Events
Intro
昨天早上看到之前關(guān)注的一個(gè) efcore 的 issue 被 closed ,于是看了一眼, ef core 新合并了一個(gè) PR,在 DbContext 中增加了 SaveChanges 相關(guān)的幾個(gè)事件,具體的變更可以參數(shù) PR https://github.com/dotnet/efcore/pull/21862
Events
之前寫過兩篇關(guān)于 EF Core 做自動(dòng)審計(jì)的文章
第一次的實(shí)現(xiàn)需要顯式繼承一個(gè) AuditDbContext ,在有些需要沒辦法修改 DbContext 或者原有 DbContext 已經(jīng)有繼承某一個(gè)類,就沒有辦法用了,可以參考?EF Core 數(shù)據(jù)變更自動(dòng)審計(jì)設(shè)計(jì)
后面結(jié)合 AOP 改進(jìn)了一版,通過一個(gè)審計(jì)切面邏輯完成自動(dòng)審計(jì),但是需要引入 AOP 組件支持,對(duì)于不想引入額外組件的項(xiàng)目來說也并非特別友好,可以參考?打造更好用的 EF 自動(dòng)審計(jì)
在這個(gè) PR 合并之后,我們可以通過 SavingChanges 事件獲取保存之前 DbContext 的狀態(tài),通過 SavedChanges 事件來獲取保存成功后的 DbContext 信息,SaveChangesFailed 事件獲取保存失敗信息
事件定義如下:
///?<summary> ///?????An?event?fired?at?the?beginning?of?a?call?to?<see?cref="M:SaveChanges"/>?or?<see?cref="M:SaveChangesAsync"/> ///?</summary> public?event?EventHandler<SavingChangesEventArgs>?SavingChanges;///?<summary> ///?????An?event?fired?at?the?end?of?a?call?to?<see?cref="M:SaveChanges"/>?or?<see?cref="M:SaveChangesAsync"/> ///?</summary> public?event?EventHandler<SavedChangesEventArgs>?SavedChanges;///?<summary> ///?????An?event?fired?if?a?call?to?<see?cref="M:SaveChanges"/>?or?<see?cref="M:SaveChangesAsync"/>?fails?with?an?exception. ///?</summary> public?event?EventHandler<SaveChangesFailedEventArgs>?SaveChangesFailed;事件參數(shù)定義如下:
///?<summary> ///?????Base?event?arguments?for?the?<see?cref="M:DbContext.SaveChanges"?/>?and?<see?cref="M:DbContext.SaveChangesAsync"?/>?events. ///?</summary> public?abstract?class?SaveChangesEventArgs?:?EventArgs {///?<summary>///?????Creates?a?base?event?arguments?instance?for?<see?cref="M:DbContext.SaveChanges"?/>///?????or?<see?cref="M:DbContext.SaveChangesAsync"?/>?events.///?</summary>///?<param?name="acceptAllChangesOnSuccess">?The?value?passed?to?SaveChanges.?</param>protected?SaveChangesEventArgs(bool?acceptAllChangesOnSuccess){AcceptAllChangesOnSuccess?=?acceptAllChangesOnSuccess;}///?<summary>///?????The?value?passed?to?<see?cref="M:DbContext.SaveChanges"?/>?or?<see?cref="M:DbContext.SaveChangesAsync"?/>.///?</summary>public?virtual?bool?AcceptAllChangesOnSuccess?{?get;?} }///?<summary> ///?????Event?arguments?for?the?<see?cref="DbContext.SavingChanges"?/>?event. ///?</summary> public?class?SavingChangesEventArgs?:?SaveChangesEventArgs {///?<summary>///?????Creates?event?arguments?for?the?<see?cref="M:DbContext.SavingChanges"?/>?event.///?</summary>///?<param?name="acceptAllChangesOnSuccess">?The?value?passed?to?SaveChanges.?</param>public?SavingChangesEventArgs(bool?acceptAllChangesOnSuccess):?base(acceptAllChangesOnSuccess){} }///?<summary> ///?????Event?arguments?for?the?<see?cref="DbContext.SavedChanges"?/>?event. ///?</summary> public?class?SavedChangesEventArgs?:?SaveChangesEventArgs {///?<summary>///?????Creates?a?new?<see?cref="SavedChangesEventArgs"?/>?instance?with?the?given?number?of?entities?saved.///?</summary>///?<param?name="acceptAllChangesOnSuccess">?The?value?passed?to?SaveChanges.?</param>///?<param?name="entitiesSavedCount">?The?number?of?entities?saved.?</param>public?SavedChangesEventArgs(bool?acceptAllChangesOnSuccess,?int?entitiesSavedCount)?:?base(acceptAllChangesOnSuccess){EntitiesSavedCount?=?entitiesSavedCount;}///?<summary>///?????The?number?of?entities?saved.///?</summary>public?virtual?int?EntitiesSavedCount?{?get;?} }///?<summary> ///?????Event?arguments?for?the?<see?cref="DbContext.SaveChangesFailed"?/>?event. ///?</summary> public?class?SaveChangesFailedEventArgs?:?SaveChangesEventArgs {///?<summary>///?Creates?a?new?<see?cref="SaveChangesFailedEventArgs"/>?instance?with?the?exception?that?was?thrown.///?</summary>///?<param?name="acceptAllChangesOnSuccess">?The?value?passed?to?SaveChanges.?</param>///?<param?name="exception">?The?exception?thrown.?</param>public?SaveChangesFailedEventArgs(bool?acceptAllChangesOnSuccess,?[NotNull]?Exception?exception):?base(acceptAllChangesOnSuccess){Exception?=?exception;}///?<summary>///?The?exception?thrown?during<see?cref="M:DbContext.SaveChanges"/>?or?<see?cref="M:DbContext.SaveChangesAsync"/>.///?</summary>public?virtual?Exception?Exception?{?get;?} }More
除了上面的審計(jì),你也可以使用通過這些事件,實(shí)現(xiàn)保存之前的自動(dòng)更新數(shù)據(jù)庫(kù)字段的值,比如 Add 或 Update 操作數(shù)據(jù)時(shí)自動(dòng)設(shè)置更新時(shí)間等信息
本文提到的特性還未正式發(fā)布,預(yù)計(jì)會(huì)在 .net5 下一個(gè)預(yù)覽版中發(fā)布,如果想現(xiàn)在要嘗試,請(qǐng)使用 efcore 的 daily build 的包,可以參考 https://github.com/dotnet/aspnetcore/blob/master/docs/DailyBuilds.md
Reference
https://github.com/dotnet/efcore/issues/15910
https://github.com/dotnet/efcore/pull/21862
總結(jié)
以上是生活随笔為你收集整理的efcore 新特性 SaveChanges Events的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 龙芯3A5000初样顺利交付流片
- 下一篇: 十分钟搭建自己的私有NuGet服务器-B