VB.net,WPF和嵌套的Datamodel:写回数据库的最佳方式?

时间:2017-11-15 09:05:02

标签: wpf vb.net ms-access datagrid

我对VB.net和WPF很陌生。但是我在PHP和JAVA编程方面有一些经验。我成功地完成了自己遇到的大部分陷阱,但现在我偶然发现了一些我认为必须已经有一种明智的解决方法。

这就是我的意思:

我使用VB.net,WPF和MS Access数据库。这是不可协商的,我无法使用其他数据库。我的Datamodel由几个嵌套对象组成,如下所示:

Public Class subSubObject
    Public Property id as int32
    Public Property description as string
End Class

Public Class subObject
    Public Property id as int32
    Public Property description as string
    Public Property subSubObjects as list (of subSubObject)
End Class

Public Class MainObject
    Public Property id as int32
    Public Property description as string
    Public Property subObjects as list (of subObject)
End Class

Public Class DataModel
    Public Property MainObjects as list (of MainObject)
End Class

我使用OLEDB连接从数据库中读取信息并创建相应的对象以反映我的数据库模型。所以在这一刻,Database和Datamodel是完全相同的。 现在我使用带有行详细信息的WPF数据网格来对数据模型进行更改。这意味着我删除了对象,创建了新对象和新的子对象等.ID由数据库引擎管理,而不是由应用程序管理。如果我在数据库中输入新的数据集,它将自动获得一个新的ID。

<DataGrid x:Name="dgDataModel" 
    AutoGenerateColumns="true" CanUserAddRows="true" ItemsSource="{Binding DataModel}">

            <DataGrid.Columns>
                <DataGridTemplateColumn Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>

                            <DataGrid x:Name="dgMainObjects"  
                                AutoGenerateColumns="False" CanUserAddRows="True" ItemsSource="{Binding Path=MainObjects}"         
                                IsReadOnly="False">

                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" IsReadOnly="True" />
                                    <DataGridTextColumn Header="Description" Binding="{Binding Path=Description}" />
                                </DataGrid.Columns>

                                <DataGrid.RowDetailsTemplate>
                                    <DataTemplate>
                                        <DataGrid  x:Name="dgRegelsaetze" AutoGenerateColumns="False" ItemsSource="{Binding Path=subObjects}">

                                            <DataGrid.Columns>
                                                <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}"/>
                                                <DataGridTextColumn Header="Description" Binding="{Binding Description}" />
                                            </DataGrid.Columns>

                                            <DataGrid.RowDetailsTemplate>
                                                <DataTemplate>

                                                    <DataGrid x:Name="dgSubSubObjects"
                                                        AutoGenerateColumns="False" ItemsSource="{Binding Path=SubSubObjects}">

                                                        <DataGrid.Columns>
                                                            <DataGridTextColumn Header="ID" Binding="{Binding Path=RegelID}" IsReadOnly="True"/>
                                                            <DataGridTextColumn Header="Beschreibung" Binding="{Binding RegelBeschr}" />
                                                        </DataGrid.Columns>

                                                </DataTemplate>                             
                                        </DataGrid> 
                                    <DataTemplate>
                                </DataGrid.RowDetailsTemplate>

                            </DataGrid>

                        </DataTemplate>
                    </DataGrid.RowDetailsTemplate>

                </DataGrid>

            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    </DataGrid.Columns>

</DataGrid>

此代码无效。它只是让您了解应用程序是如何构建的。现在,在使用wpf datagrid更改了数据模型之后,我必须将更改写回数据库。大多数情况下都没有问题。我只是定期执行INSERT和UPDATE操作。但我注意到删除操作是这里的问题。这是因为在我通过在数据网格中按DEL删除了一个对象后,它就不会留下任何迹象。由于没有ID或其他任何东西,我无法在SQL中创建所需的DELETE操作。

所以我试图通过使用datagrids的CommandManager.PreviewExecuted属性来解决这个问题。它将使我有机会定义一个子类,它将捕获已删除的对象并将其保存在单独的列表中。我可以使用此列表稍后创建DELETE命令。至少那是我的想法。

不幸的是,我发现该命令是针对级联的每个级别运行的。因此,当我删除时,让我们在我的datagrid的第三级中说一个subSubObject的实例,也会触发sub以获得较低级别。所以我最终得到的列表不仅包含已删除的对象,还包含所有它的父对象。

说实话,我不相信删除过程太复杂了。我不认为我是第一个遇到这个问题的人,所以必须有一个优雅的方法来解决这个问题。你们中有谁有想法吗?

提前致谢。 丹尼尔

1 个答案:

答案 0 :(得分:0)

假设您正在为MainObjects集合使用ObservableCollection,那么您必须处理CollectionChanged事件。看起来您也可以更改为BindingList。

StackOver reference切换到BindingList

上面的StackOverflow帖子中引用的

CodeProject article用于处理ObservableCollection CollectionChanged事件的删除。