使用New Added Row State从DataGridView将数据插入SQL

时间:2017-08-15 02:24:16

标签: vb.net datagridview

dtNew = TryCast(bs.DataSource, DataTable).GetChanges()

If (dtNew IsNot Nothing) Then
For Each dr As DataRow In dtNew.Rows
      Select Case (dr.RowState)
          Case DataRowState.Added

              Dim strSQLDelete As String = String.Empty
              strSQLDelete = String.Format("insert into employeebenefittran (empbenefitcode,amount,calamount,refno,taxclass,source,empbenefitdate,period,cycle,empno) values ('{0}',{1},{1},'{2}','{3}','{4}','{5}','{6}','{7}','{8}')", dr(0), dr(1), "", dr(2), "Y", Date.Parse(String.Format("{0}-{1}-{2}", strPeriod.Substring(0, 4), strPeriod.Substring(4, 2), 1)), strPeriod, "0E", strEmpNo)

              Using sqlConn As New SqlConnection(sDBConnection)
              If sqlConn.State = ConnectionState.Closed Then sqlConn.Open()

                  Using cmdSQLDelete As New SqlClient.SqlCommand(strSQLDelete, sqlConn)
                  cmdSQLDelete.ExecuteNonQuery()
                  End Using

              If sqlConn.State = ConnectionState.Open Then sqlConn.Close()
              End Using
    End Select
Next
End If

我已编码为使用数据源从DataGridView插入我的新增数据。但是,我发现在完成一行数据中的键之后我总是需要单击到下一行,否则它将找不到我的数据源或数据表并跳过插入。 *意味着在我点击datagridview上的新行之前,dtNew总是没有任何意义,这不是一个好的用户体验。

你对此有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您应该将 @foreach (var g in Model) { @Html.Raw(string.Format("<tr>")) int grossScore = 0; @Html.Raw(string.Format("<td>{0}</td>", g.PlayerName)) for (int s = 0; s < 18; s++) { @Html.Raw(string.Format("<td>")); int holescore = 0; var bretak = @g.Scores.Take(1).Skip(s).FirstOrDefault(); var werwee = @g.Scores.Where(b => b.Hole == s + 1).Select(i => i.Score).FirstOrDefault(); //if (bretak.Score > 0) //{ // holescore = bretak.Score; //} holescore = werwee; Html.Raw(string.Format("{0}", holescore)); //@Html.ToString(holescore); //Html.Raw(holescore); @Html.Raw(string.Format("<td>" + @holescore + "</td>")); grossScore = grossScore + holescore; @Html.Raw(string.Format("</td>")); } @Html.Raw(string.Format("<td>{0}</td>", grossScore)) @Html.Raw(string.Format("<td align=\"center\"> <button type=\"button\" class=\"btn btn-default btn-xs editBtn\" data-player-id=\"'{0}'\">Edit </button></td>", g.GameId)) @Html.Raw(string.Format("<td> <button type=\"button\" class=\"btn btn-default btn-xs deleteBtn\" data-player-id=\"'{0}'\">Delete </button></td>", g.GameId)) @Html.Raw("</tr>") } 绑定到DataTable,然后将其绑定到您的网格。看来你可能已经这样做了。然后,当您准备好保存时,您可以在BindingSource上致电EndUpdate,并将对基础BindingSource提交任何待处理的更改。

至于实际的保存,你会使一些非常简单的事情复杂化。首先,您不需要DataTableSelect Case方法允许您指定一个或多个GetChanges值,结果DataRowState将仅包含具有该状态的已更改行。改变这个:

DataTable

到此:

dtNew = TryCast(bs.DataSource, DataTable).GetChanges()

然后您可以删除dtNew = TryCast(bs.DataSource, DataTable).GetChanges(DataRowState.Added)

顺便说一下,你永远不应该使用Select Case然后将另一个成员链接到它上面。 TryCast的重点是它可以返回TryCast。如果在您的代码中发生这种情况,则会抛出Nothing。如果你知道一个事实永远不会发生,那么你应该首先使用NullReferenceExcpetion而不是DirectCast

也没有理由使用这样的循环。您应该使用适当的TryCast创建数据适配器,然后将InsertCommand传递给其DataTable方法。这样可以将Update中的所有更改保存为批处理。

无论如何,可能没有理由打电话给DataTable。如果除了您不想同时保存的添加项之外的类型可能会发生变化,您才会这样做。如果您想保存所有更改,或者只有新行,那么您也可以在数据适配器上调用GetChanges并传递原始Update