【发布时间】:2019-06-08 15:34:00
【问题描述】:
经过大量挖掘,我仍然无法找到在 .NET 中执行以下基本任务的正确方法(也许我只是找不到非常明显的东西,如果是的话,抱歉)。
在 WinForms 应用程序中,有一些 SQL 查询 ("select * from tab1 where col1 > 5");此查询的结果存储在 DataTable-Object 中。
一段时间后,我想刷新数据库中的数据。由于有一个 PrimaryKey,我将DataAdapter.Fill 与表对象一起使用,它确实可以很好地更新值。它不做的是删除数据库表中不再存在的行。
请看下面的代码。
Private connectionString As String = "Data Source=DBName;User Id=my_user;Password=my_pwd;"
Private Sub LoadData(dt As DataTable, sql As String)
Using conn = New Oracle.DataAccess.Client.OracleConnection(connectionString)
Dim cmd = New Oracle.DataAccess.Client.OracleCommand(sql, conn)
cmd.CommandType = CommandType.Text
Using da = New Oracle.DataAccess.Client.OracleDataAdapter(cmd)
conn.Open()
da.Fill(dt)
dt.PrimaryKey = New DataColumn() {dt.Columns(0)}
End Using
End Using
End Sub
Private dt As New DataTable
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
LoadData(dt, "select * from tab1 where col1 > 5")
End Sub
EDIT1:创建 DataTable 的新实例或使用它的 Clear-如果对象绑定到网格(当前记录丢失;需要重绘每个单行)。
现在,有一个解决方案,我认为这是一个解决方法。
如果我们先将 DataTable-object 中的所有行标记为“已删除”,然后从 DB 中获取所有数据,它会将现有行的状态重置为 Unchanged,将那些不在 DB 上的行保留为 @987654327 @;随后AcceptChanges 将它们从数据表中删除。
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For Each r As DataRow In dt.Rows
r.Delete()
Next
LoadData(dt, "select * from tab1 where col1 > 5")
dt.AcceptChanges()
End Sub
这行得通,但我觉得很难看。
还有一个名为"Database Change Notification"的功能,它非常好,因为它可以让人们知道添加/修改/删除行的rowids,但我们需要显式选择rowid才能删除行来自 DataTable - 这很丑陋(并不总是那么容易)。
这样做的正确方法是什么?
【问题讨论】:
-
老实说只是刷新,扔掉以前的结果,然后重新加载。在函数调用之前设置 dt = new datatable,在这种情况下,结果将被加载到新的数据表中,或者您可以在重新填充之前调用 dt.clear。
-
@Jeremy 如果 DataTable 绑定到某个网格,这会产生不良的副作用(我在帖子中添加了一个 EDIT 以澄清这一点)。
标签: .net winforms odp.net data-access