1

我目前正在开发一个 WPF MVVM 应用程序,使用 MVVM Light 作为 MVVM 框架,实体框架作为 ORM,MS 同步框架作为将本地 Sql Compact DB 与在线 SQL 数据库同步的手段。该应用程序的范围也相当复杂,因为它旨在管理资产,计算该资产在其生命周期内的使用磨损。谢天谢地,我对所有这些技术都是新手,所以无知是幸福 :) 我找到了很多关于创建工作单元模式和存储库模式的教程和信息。但是,我正在使用新的 DbContext,我已经阅读过它已经使用了这两种模式。

我当前的问题与在实体框架中使用新的 DbContext 有关。我在 VS 中使用了 DbContext Generator 模板,所以我有一个 MyDbModelContainer。我直接从我的视图模型中使用了它,它为每个 VM 创建了一个上下文,我很确定这是一个坏主意。这是我的父/子类型数据输入场景的构造函数,我在此处构造容器,它们使用 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

我想在我的视图模型的生命周期内保持上下文打开,以便我可以使用 MyDbModelContainer.MyTable.Local 进行绑定。因此,虽然这正在工作,但我应该如何正确处理这个问题?

我的直觉是我需要以某种方式将自动生成的 MyDbModelContainer 包装到一些基本上只包含我需要在该 View-Model 上使用的表和函数的类中。

我没有使用 View-Model Locator,而是使用另一个 View-Model 来管理我的视图,这个想法来自Rachel 的博客,我喜欢这个概念。但是,这意味着我要预先创建所有视图模型,并预先初始化任何视图模型依赖项。我只有一个窗口,只是在它们留在内存中的视图模型之间切换,并且在切换到新的视图模型时我没有任何方法可以关闭我的 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 中?

4

1 回答 1

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,并在激活页面时打开它。

于 2012-12-17T14:12:25.590 回答