亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 SQLite 刪除整個數據庫并使用 EF Core 重置更改跟蹤器

如何使用 SQLite 刪除整個數據庫并使用 EF Core 重置更改跟蹤器

Go
收到一只叮咚 2022-11-21 20:15:50
我有一個服務器客戶端架構,其中服務器為客戶端提供 Rest API 以同步整個數據庫數據。他們將其保存到本地 SQLite 數據庫中。該模型位于共享項目中,有時會發生變化。因此,客戶端需要更新他們本地的 SQLite 數據庫模式。這當然只發生在更新客戶端軟件之后(數據庫文件保持不變)。它通常通過刪除數據庫文件并在之后重新創建來簡單地實現。_context.Database.EnsureDeleted();_context.Database.EnsureCreated();AttachNewDataFromServerToDatabaseContext(_context);_context.SaveChanges();Rest API 服務被實例化為 singelton,并始終使用相同的數據庫上下文對象。第一次同步工作正常。但是接下來的失敗了:System.InvalidOperationException: The instance of entity type '***' cannot be tracked because another instance with the key value '{id:  ***}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.因此,盡管整個數據庫已被刪除,但更改跟蹤器仍然知道“舊”實體。我對此的看法:每次同步數據庫時實例化一個新的數據上下文可以修復它,因為更改跟蹤器從“零”開始。在我看來這不是一個好的解決方案。如果 EnsureDeleted 也“重置”更改跟蹤器或者您可以手動執行,那就太好了。你怎么看待這件事?謝謝你的幫助!
查看完整描述

2 回答

?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

  • 每次同步數據庫時實例化一個新的數據上下文可以修復它,因為更改跟蹤器從“零”開始。在我看來這不是一個好的解決方案。

我寧愿說這是“正確”的解決方案。默認情況下,上下文元數據(又名Model)按上下文類型緩存,數據庫連接由連接池維護,并且僅在需要時才打開/關閉。所以重用上下文實例的唯一好處是避免創建多個DbSet實例。

同時,跟蹤器會保留大量“實體”實例,并防止它們在SaveChanges調用后被垃圾回收,而無需任何需要。不算潛在的多線程訪問問題。

所以恕我直言,這就是要走的路——實例化新的上下文,用它做一些事情并處理它。

  • 如果 EnsureDeleted 也“重置”更改跟蹤器或者您可以手動執行,那就太好了。

確實那會很棒。但目前EnsureDeletedEF Core 和 EF Core 都沒有提供手動執行此操作的公共方式。

雖然有一種內部方法,但通常存在在未來某個 EF Core 版本中可能會更改的風險。添加

using Microsoft.EntityFrameworkCore.Infrastructure;

會允許你使用這樣的東西

_context.ChangeTracker.GetInfrastructure().ResetState();

大概之前_context.Database.EnsureDeleted();。這基本上證明你真的應該使用第一個選項(新上下文)。

更新(EF Core 3.0): ChangeTracker甚至在內部也不再公開StateManager,所以我們需要

using Microsoft.EntityFrameworkCore.Internal;

分別

_context.GetDependencies().StateManager.ResetState();

更新(EF Core 5.0):感謝評論中的Vaclav Elias,現在 ChangeTracker 公開了一個 Clear() 方法來清除所有被跟蹤實體的 DbContext。

_context.ChangeTracker.Clear();


查看完整回答
反對 回復 2022-11-21
?
浮云間

TA貢獻1829條經驗 獲得超4個贊

以下幾行對我有用。參考:https ://github.com/dotnet/efcore/issues/6282


    context.ChangeTracker

        .Entries()

        .ToList()

        .ForEach(e => e.State = EntityState.Detached);


    context.Database.EnsureDeleted();

    context.Database.EnsureCreated();


查看完整回答
反對 回復 2022-11-21
  • 2 回答
  • 0 關注
  • 119 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號