1

現在、MVVM フレームワークとして MVVM Light、ORM として Entity Framework、およびローカル Sql Compact DB をオンライン SQL データベースと同期する手段として MS Synch Framework を使用して、WPF MVVM アプリケーションに取り組んでいます。このアプリケーションは、資産を管理し、その資産の使用による消耗を計算することを目的としているため、範囲もかなり複雑です。ありがたいことに、私はこれらすべてのテクノロジーに慣れていないので、無知であっても幸いです :) Unit of Work パターンとリポジトリ パターンの作成に関する多くのチュートリアルと情報を見つけました。ただし、私が読んだ新しい DbContext は、既にこれら 2 つのパターンを使用しています。

私の現在の問題は、Entity Framework で新しい 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 を使用できるように、View-Model の存続期間中 Context を開いたままにしたいと考えています。これが機能している間、これを正しく処理するにはどうすればよいですか?

私の直感では、自動生成された MyDbModelContainer を、基本的にその View-Model で作業する必要があるテーブルと関数のみを含むいくつかのクラスにラップする必要があるということです。

私は View-Model Locator を使用していませんが、別の View-Model を使用してビューを管理しています。Rachel のブログからアイデアを得ました。コンセプトが気に入っています。ただし、これは、すべてのビュー モデルを事前に作成し、ビュー モデルの依存関係を事前に初期化していることを意味します。私はウィンドウを 1 つしか持っておらず、View-Model を切り替えているだけで、それらはメモリに残り、新しい 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 とは別に別のクラスを作成する必要がありますか?そのクラスはどのように見えるでしょうか?それはもう 1 つのクラスでしょうか?それともビジネス オペレーションに基づいて別のクラスでしょうか? . 製造を追加、更新、および削除するクラス、材料を追加、更新、および削除するクラスなど。VM のどこに挿入する必要がありますか? おそらくシェルビューモデルで?

4

1 に答える 1

0

db コンテキストに実際に触れることなく、この問題を解決できます。VM がメモリ内に残っている場合でも、VM のビューがアクティブなときにモデル インスタンスを初期化するだけでよいという考え方です。

Caliburn.Micro: Screens and Conductorsでこれを行う良い方法がありますが、実際には mvvm フレームワークに固有のものではありません。

最も基本的なケースでは、Rachel が上記のコメントで述べたようにIPageViewModel、VM のアクティブ化および非アクティブ化ロジックを処理する関数を含めるように拡張します。VM がアクティブ化されるとアクティブ化ロジックが呼び出され、VM がアクティブ化されると非アクティブ化ロジックが呼び出されます。無効化されました。

activate/deactivate の実際の呼び出しは、 のコンテナで行われ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

そうすれば、ページが非アクティブ化されたときに db 接続を閉じたり、DbContext をデタッチしたり、ページがアクティブ化されたときに開くことができます。

于 2012-12-17T14:12:25.590 に答える