我目前正在使用MVVM Light作为MVVM框架,Entity Framework作为ORM,以及MS Synch Framework作为将本地Sql Compact DB与在线SQL数据库同步的手段来处理WPF MVVM应用程序。该应用程序的范围也相当复杂,因为它旨在管理资产,计算资产在其生命周期内的使用损耗。值得庆幸的是,我是所有这些技术的新手,所以无知是幸福:)我发现了许多有关创建工作单元模式和存储库模式的教程和信息。但是,我正在使用新的DbContext,我读过它已经使用了这两种模式。
我当前的问题与在Entity Framework中使用新的DbContext有关。我在VS中使用过DbContext Generator模板,所以我有一个MyDbModelContainer。我直接从我的视图模型中使用它,它为每个VM创建一个Context,我很确定这是一个坏主意。这是我的父/子类型数据输入场景的构造函数,我在这里构造容器,并且他们使用MVVM Light将选定项目发送到子VM。
Private FatigueDbContext As FatigueModelContainer
Public Sub New()
If IsInDesignMode = False Then
FatigueDbContext = New FatigueModelContainer
FatigueDbContext.CtMaterials.Load()
CtMaterialsCollection = FatigueDbContext.CtMaterials.Local
FatigueDbContext.CtManufactures.Load()
CtManufactures = FatigueDbContext.CtManufactures.Local
End If
End Sub
我想在我的View-Model的生命周期中保持Context打开,以便我可以使用MyDbModelContainer.MyTable.Local进行绑定。因此,虽然这有效,但我该如何正确处理?
我的直觉是我需要以某种方式将自动生成的MyDbModelContainer包装到某些类中,这些类基本上只包含我需要在该View-Model上使用的表和函数。
我没有使用View-Model Locator,而是使用另一个View-Model来管理我的视图,从Rachel's blog得到了这个想法,我喜欢这个概念。但是,这意味着我正在创建所有的View-Models,并预先初始化任何视图模型依赖项。我只有一个窗口,我只是在View-Models之间切换它们留在内存中,当切换到新的View-Model时我没有办法关闭我的DbContext。
以下是Shell View-Model
的代码Public Class ShellViewModel
Inherits ViewModelBase
#Region "Fields"
Private _changePageCommand As ICommand
Private _currentPageViewModel As IPageViewModel
Private _pageViewModels As List(Of IPageViewModel)
#End Region
Public Sub New()
Dim DialogService As New ModalDialogService
' Add available pages
PageViewModels.Add(New ImportJobDataViewModel(DialogService))
PageViewModels.Add(New TestViewModel())
PageViewModels.Add(New ReverseBendUtilityViewModel(DialogService))
' Set starting page
CurrentPageViewModel = PageViewModels(0)
End Sub
#Region "Properties / Commands"
Public ReadOnly Property ChangePageCommand() As ICommand
Get
If _changePageCommand Is Nothing Then
_changePageCommand = New RelayCommand(Of IPageViewModel)(Sub(param) ChangeViewModel(param))
End If
Return _changePageCommand
End Get
End Property
Private Function IsViewPageModel(viewPageModel As IPageViewModel) As Boolean
If TypeOf (viewPageModel) Is IPageViewModel Then
Return True
Else
Return False
End If
End Function
Public ReadOnly Property PageViewModels() As List(Of IPageViewModel)
Get
If _pageViewModels Is Nothing Then
_pageViewModels = New List(Of IPageViewModel)()
End If
Return _pageViewModels
End Get
End Property
Public Property CurrentPageViewModel() As IPageViewModel
Get
Return _currentPageViewModel
End Get
Set(value As IPageViewModel)
If _currentPageViewModel IsNot value Then
_currentPageViewModel = value
RaisePropertyChanged(Function() CurrentPageViewModel)
End If
End Set
End Property
#End Region
#Region "Methods"
Private Sub ChangeViewModel(viewModel As IPageViewModel)
If Not PageViewModels.Contains(viewModel) Then
PageViewModels.Add(viewModel)
End If
CurrentPageViewModel = PageViewModels.FirstOrDefault(Function(vm) vm Is viewModel)
End Sub
#End Region
End Class
总而言之......除了自动生成的FatigueModelContainer之外,我应该创建一个单独的类,该类看起来是什么样的,它只是一个类,还是基于它的单独类业务运营。例如添加,更新和删除制造的类,添加,更新和删除材料的类等等。我应该将它插入VM?大概是在Shell-View-Model?
答案 0 :(得分:0)
您可以在不真正触及数据库上下文的情况下解决此问题。我们的想法是,即使VM保留在内存中,您也只需要在VM的视图处于活动状态时初始化模型实例。
在Caliburn.Micro: Screens and Conductors中有一种很好的方法可以解决这个问题,但它并不是特定于mvvm框架的。
在最基本的情况下,正如Rachel在上面的评论中提到的那样,您将IPageViewModel
扩展为包含处理VM的激活和停用逻辑的函数:激活VM时调用激活逻辑,当VM被停用时,将调用停用逻辑。
激活/取消激活的实际调用将在IPageViewModels
的容器中进行,例如:
Public Property CurrentPageViewModel() As IPageViewModel
Get
Return _currentPageViewModel
End Get
Set(value As IPageViewModel)
If _currentPageViewModel Is value Then
Return
End If
If _currentPageViewModel IsNot Nothing Then
_currentPageViewModel.Deactivate()
End If
_currentPageViewModel = value
If value IsNot Nothing Then
value.Activate()
End If
RaisePropertyChanged(Function() CurrentPageViewModel)
End Set
End Property
这样,您可以在停用页面时关闭数据库连接/分离DbContext,并在激活页面时将其打开。