我對我的MVVM應用程序(以前稱爲WinRT,現在針對UWP)關於數據訪問的體系結構非常困惑。我很不確定如何在UI中傳播更改以及將數據訪問權限放在哪裏。MVVM體系結構:一種模型 - 幾種視圖模型+數據訪問的地方
這裏的基本架構:
- 模型層:包含的型號只有自動屬性(引用了其他車型沒有導航性能,只是IDS,所以他們基本上只是數據庫的表示)。他們不實施INotifyPropertyChanged。
- 數據訪問層:使用sqlite-net將模型存儲在數據庫中的存儲庫。它暴露了基本的CRUD操作。它從模型層返回並接受模型。
- 的ViewModels:
- 的ViewModels爲模特:他們環繞模式和揭露性質。有時我雙向綁定控件的內容(例如TextBoxes)到屬性。然後設置者訪問數據層以堅持這一改變。
- PageViewModal for Views:它們包含上面的ViewModels和Commands。許多命令已經變得非常長,因爲它們執行數據訪問,執行特定於域的邏輯並更新PageViewModels屬性。
- 視圖(頁面):它們結合PageViewModels並通過的DataTemplate到的ViewModels爲模特。有時候會有雙向數據綁定,有時我會使用命令。
我現在有幾個問題與此架構:
問題1:一個模型可以在屏幕上幾個宮殿來表示。例如,顯示一個類型的所有可用實體列表的主 - 細節視圖。用戶可以選擇其中的一個,並在詳細視圖中顯示其內容。如果用戶現在在詳細視圖中更改屬性(例如,模型的名稱),則更改應立即反映在主列表中。這樣做的最好方法是什麼?
- 已有一個ViewModel的型號爲?我不認爲這很有道理,因爲主列表只需要很少的邏輯,而詳細視圖更多。
- 讓模型實現INotifyPropertyChanged並因此將更改傳播到ViewModels?我遇到的問題是數據層目前不能保證它在一個模型ID上對兩個讀取操作返回的對象是相同的 - 它們只包含從數據庫中讀取的數據,並在讀取時新創建(我認爲這就是sqlite-net的工作方式)。我也不確定如何避免由於ViewModels中的所有PropertyChanged事件訂閱而發生內存泄漏。我應該實現IDisposable並讓PageViewModel調用其子項的Dispose()方法嗎?
- 我目前在我的數據訪問層上有一個DataChanged事件。只要發生創建,更新或刪除操作,就會調用它。可以同時顯示的每個ViewModel監聽此事件,檢查已更改的模型是否爲ViewModel的模型,然後更新其自己的屬性。我再次遇到了內存泄漏的問題,並且這種情況變得緩慢,因爲太多的ViewModel必須檢查更改是否真的適合他們。
- 另一種方式?
問題2:我也不確定我訪問數據的地方是否真的很好選擇。 PageViewModel已經變得非常複雜,基本上都做了。所有ViewModel都需要我的架構知識數據層。
我一直在考慮使用sqlite-net來取消數據訪問,並使用Entity Framework 7來代替。這是否可以解決上述問題,也就是說,當我使用相同的上下文時,它是否可以保證一個模型的對象標識?我也認爲這會簡化ViewModels,因爲我很少需要讀取操作,因爲這是通過導航屬性完成的。
我也一直在想,在MVVM應用程序中是否有兩種方式的數據綁定是好主意,因爲它需要屬性設置器調用數據訪問層來保持更改。只做單向綁定並通過命令堅持所有更改會更好嗎?
如果有人能評論我的架構並提出改進建議或指出關注我的問題的MVVM體系結構上的優秀文章,我將非常高興。
我想我要添加一個數據服務層,目前所有ViewModel訪問DAL的接口。我的數據訪問已經是異步的,但我正在考慮將其設爲**同步**,因爲我通常連續進行數百次讀取操作。 (更少但更復雜的需要直接暴露sqlite-net功能。)這會降低性能,因爲每個小請求都有創建任務的開銷(這是sqlite-net的做法),並且也阻止了使用的交易。因此,訪問DAL將是同步的,但新的數據服務層將是異步的。 – SebastianR
並感謝您的長時間回答,CarbineCoder!這已經幫了我不少。 – SebastianR
乾杯...我很高興這很有幫助。除非你做錯了,否則你不必擔心任務創建的開銷。數據服務層的想法是好的,需要的。除非您證明異步導致問題不要刪除它。無需證明,您可能會通過進行優化前的優化來損害系統。我建議不要這樣做,除非你可以模擬你的方法並測量差異。 – CarbineCoder