2016-11-13 45 views
1

我刚刚开始自学与vb.net数据库访问和我一直在使用this as a reference。我的MS Access数据库比我参考设置关系数据库后的示例稍微复杂一些。我有两张桌子;球员和村庄。每个玩家都可以拥有一个更加多的村庄(1对多的关系),这种关系是在球员表中的唯一密钥,并在村表用于定义村的所有者玩家ID之间的捆绑。以下是我如何向数据库添加新玩家的方法;麻烦与MS访问自动编号字段和VB.net

Public Sub NewPlayer(ByVal playerName As String) 
    Dim playerID As Integer = getLastIdent("Players") + 1 
    Dim tmpnum As Integer = playerID 

    Dim dsNewRow As DataRow 
    Dim Sql As String 

    Sql = "SELECT * FROM Players" 

    da = New OleDb.OleDbDataAdapter(Sql, con) 
    da.Fill(ds, "Players") 

    Dim cb As New OleDb.OleDbCommandBuilder(da) 

    dsNewRow = ds.Tables("Players").NewRow() 

    dsNewRow.Item("ID") = playerID 
    dsNewRow.Item("NameP") = playerName 
    dsNewRow.Item("Coins") = 0 


    ds.Tables("Players").Rows.Add(dsNewRow) 

    da.Update(ds, "Players") 

    Call NewVillage(playerName, playerID) 
End Sub 

的getLastIdent子程序是我在寻找的玩家ID领域使用的最后一个值的尝试;

Public Function getLastIdent(ByVal tblname As String) 
    Dim sql As String = "SELECT @@IDENTITY FROM " & tblname 
    Dim cmd As New OleDb.OleDbCommand(Sql, con) 
    Return cmd.ExecuteScalar() 
End Function 

但是这根本不起作用(无论如何返回0)。球员们实际上可以顺利创建(不正确的ID号,似乎在某些点与数据库中正确递增自动编号来修复自身然而到村分配给新的球员,我跑NewVillage;

Public Sub NewVillage(ByVal playerName As String, ByVal playerID As Integer) 
    Dim numVils As Integer = getVilCount() 
      Dim xpos As Integer 
    Dim ypos As Integer 
    xpos = CInt(Rnd()*50) 
    ypos = CInt(Rnd()*50) 


    Dim dsNewRow As DataRow 
    Dim Sql As String 

    Sql = "SELECT * FROM Villages" 

    da = New OleDb.OleDbDataAdapter(Sql, con) 
    da.Fill(ds, "Villages") 

    Dim cb As New OleDb.OleDbCommandBuilder(da) 

    dsNewRow = ds.Tables("Villages").NewRow() 

    dsNewRow.Item("ID") = numVils + 1 
    dsNewRow.Item("NameV") = playerName & "'s Village" 
    dsNewRow.Item("Xpos") = xpos 
    dsNewRow.Item("Ypos") = xpos 
    dsNewRow.Item("Owner") = playerID 


    ds.Tables("Villages").Rows.Add(dsNewRow) 

    da.Update(ds, "Villages") 

End Sub 

这这里是整个事情的崩溃,这是传递给子程序的playerID是不是与我刚创建的播放器相关联的正确值(在脸上没有叫这个名字的任何球员,因为它总是试图playerID = 1自动编号,由于删除失败的行开始高于)。

所以,我怎么能去哪里弄个从球员表中的ID的真实价值?是否有一些电话,我可以作出这样的FORC es AutoNumber更新,然后我可以重新检查它?

+0

的[选择可能的复制@ @IDENTITY WHERE在Access](http://stackoverflow.com/question S/34269518 /选择,身份,其中,在接入) – topshot

+0

您插入新的球员没有ID。然后找到新的ID是什么。然后用这个ID调用NewVillage。 – topshot

回答

1

我过去所做的是勾OleDbDataAdapter的的RowUpdated事件和那个勾,执行身份检索命令。

首先,定义将被用于在一个模块水平执行所述身份子句和添加的方法,以实例化该命令:

Private cmdGetIdentity As OleDb.OleDbCommand 

Private Sub CreateIdentityCommand(con As OleDbConnection, tblName As String) 

    Dim sql As String = "SELECT @@IDENTITY FROM " & tblName 
    cmdGetIdentity = New OleDb.OleDbCommand(sql, con) 

End Sub 

接下来,创建将被用于检索的事件处理程序身份(因为每个表包含一个ID列,该代码可以被用于两个你的表的):

Private Sub RowUpdated(ByVal sender As Object, ByVal e As OleDbRowUpdatedEventArgs) 

    If e.Status = UpdateStatus.Continue AndAlso e.StatementType = StatementType.Insert Then 
     ' Execute the command and move it into the row 
     e.Row("ID") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString()) 
     ' Ensure the row's changes are accepted 
     e.Row.AcceptChanges() 
    End If 

End Sub 

最后,修改现有的方法来实例化身份命令,勾新事件,并删除现有的试图设置ID的代码。在NewVillage,例如,改变:

da = New OleDb.OleDbDataAdapter(Sql, con) 

da = New OleDb.OleDbDataAdapter(Sql, con) 
    CreateIdentityCommand(con, "Villages") 
    AddHandler da.RowUpdated, AddressOf RowUpdated 

,然后取下行:

 Dim numVils As Integer = getVilCount() 

和:

 dsNewRow.Item("ID") = numVils + 1 
+0

感谢您的帮助。这仍然会导致在我的其他数据库中使用错误的索引(基本上,在我创建一个玩家后,我想要创建一个村庄并通过在村庄表中使用玩家唯一ID将该村庄分配给玩家)。出于某种原因,使用你的代码,然后检查最后一行中第一个位置的值(传递给村庄创建者)似乎通过了错误的值。这就像是在我进入村庄之后,ID的更新发生了 - 无论如何,每当我创建一个球员时都会强迫这种情况发生? – FraserOfSmeg