2016年9月24日土曜日

VB EF6 Entity Framework お試し 3 データ操作 表示

VB EF6  Entity Framework お試し 2 データソース作成 に続く作業です。
Data Source を生成しました。
さぁ、いよいよ、 本丸。
データ操作です。


前回 で、準備は整いました。  これからが佳境です。  とは言っても、動けば良し!レベルですが ... 。.

実は DataGrid にデータを表示するだけなら簡単です。
でも、 検索して見れば分かりますが、 その先の操作となると、ぐっと、例は減ります。
Desktop App. として書くのは茨でした。.

そして、作業前に書いて置きたい事があります。
それは、 Database のフロントエンドとなる プログラムの書き方 です。
色々な方法論や画面設計が考えられますし、 一覧形式で行くか 個別形式で行くか、の考え方もあります。
閲覧と編集を混在させるか、個別に扱うか、と言った考慮点もあります。
また、実際には、入力検証や、相互関係等も有り、 単純ではありません。.

ここでは、一覧形式で、閲覧と編集とを Button で切り替え、
編集は一覧の中で行い、追加と削除は一覧外の Button & TextBox で行う とします。
そして、Relation は差し当たり無視して単独 Table を扱い、
Primary Key は変更せず、追加削除で対応して貰う もの を想定します。
例外処理や入力検証も除外して説明します。

前回に引き続き、 写真管理システムから "Camera" Table で 説明します。


先ずは、データを表示させて見ます。

xaml 変更なし

code VB (参考用 / 後程 削除する予定の Using ブロック)
Class MainWindow

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded

        Dim CameraViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("CameraViewSource"), System.Windows.Data.CollectionViewSource)
        'Load data by setting the CollectionViewSource.Source property:
        'CameraViewSource.Source = [generic data source]

        Using myEntities As New PhotoDataEntities
            Dim query = From db In myEntities.Cameras Select db Order By db.CameNo
            CameraViewSource.Source = query.ToList
        End Using

    End Sub
End Class


これで、 DataGrid 上に .mdf ファイルのデータが現れ、 データの加工も可能な状態です。
追加も削除も 勿論 可能です。
しかし、 飽く迄も、DataGrid 上での事。
Database (.mdf) には反映されませんし、 Database 上の制約も 無視した 状態です。
重複が認められない Primary Key 制約の ID (ここでは CameID ) にも、 既に在る値が入力出来てしまいます。
Null 不可の列でも同様に未入力状態が許容されています。
この事をよく覚えて置いて下さい。  対策が必要と言う事ですね。.



それから、myEntities と宣言した変数には、 Database との同期を取る為の仕組みがありますが、
それは、その変数のスコープ内で行われます。
Console App なら問題ないのですが、 WPF の様に、画面を用意して操作を待ち受ける場合には、
Using で囲われていては機能しないと思います。
Dim myEntities As ... と myEntities.Dispose() とに 分離して、 然るべき場所に書き直す必要があるでしょう。

先に書いた様に、 閲覧と編集を分離し、各制約をクリアする為に、
既存データで かつ ID 列以外 の編集は DataGrid の中で行い、 その確定(同期 永続化)は Button を設け、
追加と削除は DataGrid で禁止し、 別の Contorl を用意しましょう。

myEntities へは myEntities.Database.ExecuteSqlCommand で直接 Database へ Query を投げる場合も想定して、
何か変更を行う度に、再取得させるロジックとします。

その準備の為に以下の コード変更を行って下さい。  動けば良し!レベル.


xaml 抜粋 追加部分
        </DataGrid>
        <Button x:Name="Button1_Edit" Content="Edit/Show" HorizontalAlignment="Left" Margin="20,0,0,10" VerticalAlignment="Bottom" Width="75"/>
        <TextBlock x:Name="TextBlock_Edit" HorizontalAlignment="Left" Margin="31,0,0,40" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Bottom"/>
        <Button x:Name="Button2_Save" Content="Save" HorizontalAlignment="Left" Margin="416,0,0,10" VerticalAlignment="Bottom" Width="75"/>
        <Button x:Name="Button3_Add" Content="Add" HorizontalAlignment="Left" Margin="158,0,0,10" VerticalAlignment="Bottom" Width="75"/>
        <Button x:Name="Button4_Del" Content="Delete" HorizontalAlignment="Left" Margin="283,0,0,10" VerticalAlignment="Bottom" Width="75"/>
        <TextBox x:Name="TextBox3_Add" HorizontalAlignment="Left" Height="23" Margin="158,0,0,35" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Bottom" Width="75"/>
        <TextBox x:Name="TextBox4_Del" HorizontalAlignment="Left" Height="23" Margin="283,0,0,35" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Bottom" Width="75"/>

    </Grid>
code VB 上述の code VB で Using ブロックを削除してから編集して下さい。
Class MainWindow
    Private myEntities As New PhotoDataEntities

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded

        'Dim CameraViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("CameraViewSource"), System.Windows.Data.CollectionViewSource)
        'Load data by setting the CollectionViewSource.Source property:
        'CameraViewSource.Source = [generic data source]


        ReBindToDataGrid()

        Me.CameraDataGrid.IsReadOnly = True
        Me.TextBlock_Edit.Text = "Show"
        Me.Button2_Save.IsEnabled = False
        Me.Button3_Add.IsEnabled = False
        Me.Button4_Del.IsEnabled = False
    End Sub

    Private Sub MainWindow_Closing(sender As Object, e As ComponentModel.CancelEventArgs) Handles Me.Closing
        myEntities.Dispose()
    End Sub

    Private Sub ReBindToDataGrid()
        Dim CameraViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("CameraViewSource"), System.Windows.Data.CollectionViewSource)
        'Load data by setting the CollectionViewSource.Source property:
        'CameraViewSource.Source = [generic data source]

        Dim query = From db In myEntities.Cameras Select db Order By db.CameNo

        CameraViewSource.Source = query.ToList

        'GetNewID()
    End Sub

    Private Sub Button1_Edit_Click(sender As Object, e As RoutedEventArgs) Handles Button1_Edit.Click
        Me.CameraDataGrid.IsReadOnly = Not Me.CameraDataGrid.IsReadOnly
        Me.TextBlock_Edit.Text = IIf(Me.CameraDataGrid.IsReadOnly, "Show", "Edit")
        Me.Button2_Save.IsEnabled = Not Me.CameraDataGrid.IsReadOnly
        Me.Button3_Add.IsEnabled = Not Me.CameraDataGrid.IsReadOnly
        Me.Button4_Del.IsEnabled = Not Me.CameraDataGrid.IsReadOnly
    End Sub

    Private Sub Button2_Save_Click(sender As Object, e As RoutedEventArgs) Handles Button2_Save.Click

    End Sub

    Private Sub Button3_Add_Click(sender As Object, e As RoutedEventArgs) Handles Button3_Add.Click

    End Sub

    Private Sub Button4_Del_Click(sender As Object, e As RoutedEventArgs) Handles Button4_Del.Click

    End Sub

End Class

今の処、 内容的には、 先の画面と 大きく変わりません。
Control 類を増やしましたが、 ロジックの実装はしていないので、見た目だけです。
単に、 閲覧 ( ReadOnly ) が選べる様になっただけです。

では、次回 VB EF6  Entity Framework お試し 4 データ操作 更新 でお会いしましょう。



0 件のコメント:

コメントを投稿