使用DataAdapter通过DataGridView自定义数据库更新

时间:2012-12-02 18:54:36

标签: sql vb.net visual-studio-2010 datagridview

我的DataGridView控件是DataSource绑定到TableAdapter。

该表保存每日销售额:

Date         Sales
12/03/2012   100
12/04/2012   50
12/06/2012   120

我希望DataGrid还显示没有使用空单元格进行销售的日期:

Date         Sales
12/03/2012   100
12/04/2012   50
12/05/2012   
12/06/2012   120

如果我在网格视图中更改了emtpy单元格(零销售额),我希望将其作为新行写入表中,否则不应将其写入表中。 DB是本地Access文件。

3 个答案:

答案 0 :(得分:0)

您最好的选择可能是使用OnRowDataBound并在逐行应用时操纵数据。

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.onrowdatabound.aspx

答案 1 :(得分:0)

我建议在这种情况下手动处理转换,例如,在DataAdapter和DataGridView之间创建一个代理类,这样它们就不会直接连接。这样DataAdapter将为您保存到数据库,您只需进行转换。

编辑:以下是一些让您入门的建议。下面的代码将创建一个虚拟表,您可以将其用于测试目的 - 它根本不依赖于DataAdapter:

Dim originalDataTable As New DataTable
With originalDataTable.Columns
  .Add("Date", GetType(DateTime))
  .Add("Sales", GetType(Integer))
End With
With originalDataTable.Rows
  .Add({#12/3/2012#, 100})
  .Add({#12/4/2012#, 50})
  .Add({#12/6/2012#, 120})
End With

现在准备必要的结构,你需要这个字典,所以最好声明一个类级变量 - 可能是你的情况下的一个表单:

Dim salesDictionary As New Dictionary(Of Date, DataRow)
For Each row As DataRow In originalDataTable.Rows
  salesDictionary.Add(row("Date"), row)
Next

Dim minDate As DateTime = salesDictionary.Keys.Min
Dim maxDate As DateTime = salesDictionary.Keys.Max
Dim newTable As DataTable = originalDataTable.Clone
Dim currentDate As DateTime = minDate
Do
  Dim row As DataRow = Nothing
  If salesDictionary.TryGetValue(currentDate, row) Then
    newTable.ImportRow(row)
  Else
    newTable.Rows.Add({currentDate, Convert.DBNull})
  End If
  currentDate = currentDate.AddDays(1)
Loop While currentDate <= maxDate

将您的DataGridView绑定到newTable而不是originalDataTable,并在准备好提交更改时,手动更新originalDataTable中的相关记录,如下所示:

For Each row As DataRow In newTable.Rows
  Dim newSalesValue As Object = row("Sales")
  Dim originalRow As DataRow = Nothing
  If salesDictionary.TryGetValue(row("Date"), originalRow) Then
    If newSalesValue Is Convert.DBNull Then
      originalRow.Delete()
    Else
      originalRow("Sales") = row("Sales")
    End If
  ElseIf newSalesValue IsNot Convert.DBNull Then
    originalDataTable.ImportRow(row)
  End If
Next

然后使用DataAdapter更新数据库。

答案 2 :(得分:0)

在这种情况下,我会不同地处理数据检索和存储。

对于Select语句,我建议你构建一个permenat表,说10000行,2列,1到10000之间的整数之一,以及过去一天足够的日期之一,以便有用(1 / 1/1900?1/1/2000?)并且上升到10000天后。

然后,您可以使用此表中的视图(查询)左连接到日期列上具有适当开始和停止日期的表,这将利用最佳属性orf RDMS - 数据检索和匹配。不幸的是,这个查询不可更新。

回到另一个方向,对于已经填充的行,您需要更新它们,但对于空值的行,您需要插入它们。

我会警告你我没有尝试过这个,我不确定访问是否可以处理它,但是......如果你设置dbdataadaptor的Update属性来运行一个插入(对于原来的空行)和按顺序更新(对于原始填充的行),那么你应该是甜蜜的。

更新似乎我错了 - 如果您编写以下查询,查询可以直接在访问中更新

SELECT     IndexTable.dateIndex, Sales.Sales
FROM       IndexTable
           LEFT OUTER JOIN
           Sales ON IndexTable.dateIndex = Sales.SaleDate)
WHERE      (IndexTable.dateIndex >=
                      (SELECT     MIN(SaleDate) AS Expr1
                        FROM          Sales Sales_2)) AND 
           (IndexTable.dateIndex <=
                      (SELECT     MAX(SaleDate) AS Expr1
                        FROM          Sales Sales_1))

并绑定它,您所做的任何更改都应该流回到表中。