[英]WPF app with static DbContext in ViewModel
我正在使用MVVM,Code-First和存儲庫模式開發WPF應用程序。 我需要有一個后台任務,它處理來自客戶端的Web服務器請求並將新數據保存到數據庫中。
問題是每個ViewModel都有一個屬性(ObservableCollection),它獲取Repository.GetObservableCollection()。 因此每個ViewModel都有一個存儲庫實例,它具有相同的DbContext(因此在保存復雜實體時我不會得到DbException)。 這個DbContext長期存在,直到每個倉庫中的應用程序結束,並從MainViewModel注入到虛擬機的構造器。
當我從后台任務將新數據保存到數據庫時,GUI不會更新,因為我在那里使用不同的DbContext(我必須由於並發請求):
using (var db = new DbContextManager())
{
var client = new Client();
db.Client.Add(client);
db.SaveChanges();
}
有兩種方法,我嘗試過:
將新數據保存到數據庫時,還要將實體添加到存儲庫。
Application.Current.Dispatcher.Invoke(()=> {_ clientAdpository.Add(client);});
這樣,實體會立即出現在GUI中,但也有輕微的滯后(移動窗口時),我無法更新現有實體的屬性。
問題是如何重構這一點以允許GUI和后台與實體交互。 如何正確組合存儲庫和MVVM?
你使用綁定機制嗎? 您可以在更改后更新集合(假設您的VM實現了INotifyPropertyChanged
接口)。
不要將ViewModel實體與DB DataContext
直接鏈接 。 您需要在ViewModel中定義ObservableCollection
及其在XAML中的綁定。
之后,您將通過調用持久層中的函數來異步更新集合。 因此,最好使用LoadAsync
,或者將數據庫檢索包裝到Task中。 這種方法將起作用,因為await
將捕獲UI線程的SynchronizationContext
並將更新UI線程中的組件。
實際的DataContext
必須隱藏在該持久層中,並且ViewModel必須保持未知 。
如果我沒有將DbContext傳遞給ViewModels(后者又將其傳遞給它的存儲庫),我如何獲取存儲庫的上下文,所以我可以調用
point void LoadAll() {
context.Set<T>().Load();
}
和
public ObservableCollection<T> GetObservableCollection() {
return context.Set<T>().Local;
}
根據我的回答,ViewModel可以調用持久層函數來加載集合(甚至不需要從持久層返回的類型是可觀察的)。 關鍵是你不會返回void
,你可能會使用LoadAsync
以便在將返回的數據分配給ViewModel屬性的基礎集合時await
它。
所以我必須使用
Dispatcher.Invoke
與repos / viewmodels進行交互
不, 不要使用Dispatcher.Invoke
與存儲庫數據庫上下文進行交互。 與DB 異步進行交互。 請注意, Dispatcher.Invoke
僅適用於UI層。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.