【问题标题】:VB.net, WPF and nested Datamodel: Best way to write back into Database? [closed]VB.net、WPF 和嵌套数据模型:写回数据库的最佳方式? [关闭]
【发布时间】:2018-04-28 10:20:20
【问题描述】:

我对 VB.net 和 WPF 还是很陌生。不过,我主要在 PHP 和 JAVA 编程方面有一些经验。我设法让自己克服了遇到的大部分陷阱,但现在我偶然发现了一些我认为必须已经有一个聪明的方法来解决的问题。

这就是我的意思:

我正在使用 VB.net、WPF 和 MS Access 数据库。这是不可协商的,我无法使用另一个数据库。我的数据模型由多个嵌套对象组成,如下所示:

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 数据网格更改数据模型后,我必须将更改写回数据库。大多数情况下没有问题。我只是做常规的 INSERT 和 UPDATE 操作。但我注意到删除操作是这里的问题。这是因为在我通过在数据网格中按 DEL 删除了一个对象后,它就消失了,没有留下任何存在的迹象。由于没有 ID 或其他任何东西,我无法在 SQL 中创建所需的 DELETE 操作。

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

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

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

提前致谢。 丹尼尔

【问题讨论】:

    标签: wpf vb.net ms-access datagrid


    【解决方案1】:

    假设您将 ObservableCollection 用于 MainObjects 集合,您必须处理 CollectionChanged 事件。看起来您也可以更改为 BindingList。

    StackOver reference 切换到 BindingList

    上述 StackOverflow 帖子中引用的CodeProject article 用于使用 ObservableCollection CollectionChanged 事件处理删除。

    【讨论】:

    • 嗨,那个答案给了我正确的提示。我现在所做的是为我的每个班级添加一个“已删除项目集合”。然后我使用 collectionChanged 事件将已删除对象的副本放入该集合中。现在我可以使用它们来创建我的 DELETE-Statement。我只是对事件不够熟悉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2018-03-03
    相关资源
    最近更新 更多