2016-10-27 47 views
0

Datagrid to dbf数据库更新类型的解决方案找不到任何地方,如果有人解决这个问题请回复我。 错误 - 对于不返回任何键列信息的SelectCommand,不支持UpdateCommand的动态SQL生成。 我的代码是Datagrid to dbf数据库使用vb.net

Dim con As New OleDbConnection 
Dim ds As New DataSet 
Dim dt As New DataTable 
Dim da As New OleDbDataAdapter 
Dim con1 As New OleDbConnection 
Dim ds1 As New DataSet 
Dim dt1 As New DataTable 
Dim da1 As New OleDbDataAdapter 


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    con.ConnectionString = "Provider=vfpoledb.1;Data Source=C:\dbf_folder;Collating Sequence=machine;" 
    con.Open() 
    ds.Tables.Add(dt) 
    da = New OleDbDataAdapter("Select * from area.dbf", con) 
    Dim cb = New OleDbCommandBuilder(da) 
    cb.QuotePrefix = "[" 
    cb.QuoteSuffix = "]" 
    da.Fill(dt) 
    dt.Merge(dt1) 
    dbfdatagrid.DataSource = dt.DefaultView 
    con.Close() 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    con1.Close() 
    con1.ConnectionString = "Provider=vfpoledb.1;Data Source=C:\dbf_folder1;Collating Sequence=machine;" 
    con1.Open() 
    da1 = New OleDbDataAdapter("Select * from area.dbf", con1) 
    Dim cb = New OleDbCommandBuilder(da1) 
    cb.QuotePrefix = "[" 
    cb.QuoteSuffix = "]" 
    Dim columns(5) As DataColumn 
    columns(4) = dt.Columns("NAME") 
    dt.PrimaryKey = columns 

    da1.Fill(dt1) 
    da1.Update(dt) 

回答

0

在你的代码看(我不知道VB,我更多的是C#的家伙),它不是VFP的事,你的代码是奇怪给予任何数据库。

当数据库是VFP时,您不应该使用这些QuotePrefix和QuoteSuffix。这本身就创建了一个越野车更新命令。您也可以手动编写更新命令。

尽管我不知道VB,不是你的代码创建了一个6元素的DataColumn数组,并且只设置了第5个元素,而将其他元素设置为NULL作为主键?目的是什么?实际上,如果您没有有效的主键,则不需要指定主键(然后您需要手动编写更新命令 - 如果您可以构建有效的更新命令以正确更新行,这也是您的问题你需要)。我们假设,您将遵循良好的数据库原则并在表中包含主键。那么你不需要写手动更新,只需要CommandBuilder为你构建它。即:

Sub Main() 
    Dim tbl As New DataTable() 

    Dim adapter = New OleDbDataAdapter("select * from Customer", "Provider=VFPOLEDB;Data Source=C:\PROGRAM FILES (X86)\MICROSOFT VISUAL FOXPRO 9\SAMPLES\data") 

    adapter.Fill(tbl) 

    Dim cb = New OleDbCommandBuilder(adapter) 
    adapter.UpdateCommand = cb.GetUpdateCommand() 

    Dim f = New Form() 
    Dim btn = New Button With { 
     .Top = 10, 
     .Text = "Update" 
    } 
    Dim dgv = New DataGridView With { 
     .Top = 50, 
     .DataSource = tbl 
    } 
    f.Controls.AddRange(New Control() {btn, dgv}) 
    AddHandler btn.Click, Sub(sender, args) 
           adapter.Update(tbl) 
          End Sub 

    f.Show() 
End Sub 

如果你有一个表没有主键生成器可以从架构中提取,那么你可以为编写自己手动更新代码。仅用于采样,假设您在c:\ Temp中有一个名为NoPK(v1 i,v2 c(10))的表格。与OleDb的

Sub Main() 
    Dim tbl As New DataTable() 

    Dim adapter = New OleDbDataAdapter("select * from NoPK", "Provider=VFPOLEDB;Data Source=c:\Temp") 

    adapter.Fill(tbl) 

    adapter.UpdateCommand = New OleDbCommand("update NoPK set v2=? where v1=?", adapter.SelectCommand.Connection) 
    adapter.UpdateCommand.Parameters.AddWithValue("p1", "").SourceColumn = "v2" 
    adapter.UpdateCommand.Parameters.AddWithValue("p2", 0).SourceColumn = "v1" 


    Dim f = New Form() 
    Dim btn = New Button With { 
     .Top = 10, 
     .Text = "Update" 
    } 
    Dim dgv = New DataGridView With { 
     .Top = 50, 
     .DataSource = tbl 
    } 
    f.Controls.AddRange(New Control() {btn, dgv}) 
    AddHandler btn.Click, Sub(sender, args) 
           adapter.Update(tbl) 
          End Sub 

    f.Show() 
End Sub 

需要注意的是:虽然它没有索引信息,它是一个免费的表(生成器无法确定PK),我们知道,V1是我们的重点,我们只想更新V2,可以这样做,参数应该以命令文本中相应的占位符(?)以相同的顺序添加到集合中(IOW不会先添加p2)。