[英]how to use sql Bulkcopy to insert datagridview rows in table
我想將 datagridview 行插入到 sql server 表中......現在使用此代碼將來自 DataGridView 的行值插入表中:
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
}
}
object[] cellValues = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}
return dt;
}
private void InsertDTtoDB(string ConnectionString, string TableName, DataGridView DGV)
{
DataTable dt = new DataTable();
dt = GetDataTableFromDGV(DGV);
using (SqlConnection cn = new SqlConnection(ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
copy.ColumnMappings.Add(0, 1);
copy.ColumnMappings.Add(1, 2);
copy.ColumnMappings.Add(2, 3);
copy.ColumnMappings.Add(3, 4);
copy.ColumnMappings.Add(4, 5);
copy.DestinationTableName = TableName;
copy.WriteToServer(dt);
}
}
}
但是插入數據時遇到問題:datatgridview 中的空行(啟用添加行)存儲在最后一個表行中! 請注意圖片幫助:
首先,一些可以幫助您更好地理解在 C# 中編寫代碼的一般觀察:
// this line is declaring a new variable named 'dt'
// and assigning it an instance of a new DataTable
DataTable dt = new DataTable();
// this line is immediately overwriting the new DataTable
// assigned to 'dt' with the DataTable returned from 'GetDataTableFromDGV'
dt = GetDataTableFromDGV(DGV);
上面應該寫成聲明變量然后賦值:
DataTable dt = GetDataTableFromDGV(DBV);
以下來自GetDataTableFromDGV
,僅當該列可見時才會向 DataTable 添加一列:
foreach (DataGridViewColumn column in dgv.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
}
}
然后在InsertDTtoDB
中使用來自上面的 DataTable 的結果,它顯然期望在預定義的序數位置中設置一定數量的列:
copy.ColumnMappings.Add(0, 1);
// etc...
以上是在GetDataTableFromDGV
中創建的 DataTable 之間創建一個非常脆弱的關系,它要求 Column 可見,然后在InsertDTtoDB
。
而不是在 DataTable 和 SqlBulkCopy.ColumnMappings 之間使用脆弱的序數關系,而是使用字段的名稱來創建 DataTable,然后映射到 SqlBulkCopy。 `GetDataTableFromDGV' 中的 foreach 然后變成:
// assumes the columns in the DataGridView are named as follows:
var columns = new[] {"Id", "Invoice_Id", "Software_Id", "Price", "Quantity", "Sum" }
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
// note: this is case-sensitive
if (columns.Contains(column.Name))
{
dt.Columns.Add();
}
}
然后InsertDTtoDB
中的InsertDTtoDB
變成:
copy.ColumnMappings.Add("Invoice_Id", "DestinationCol1");
copy.ColumnMappings.Add("Software_Id", "DestinationCol2");
// etc...
將行添加到GetDataTableFromDGV
的 DataTable 時, cellValues
變量在 foreach 循環外聲明,但值在內部 for 循環中不斷被覆蓋。 不是將對象數組添加到 DataTable,而是使用實際的列名來構建 DataRow 並將新的 DataRow 添加到 DataTable。
考慮到上述情況, GetDataTableFromDGV
方法變為:
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
// use your actual columns names instead of Col1, Col2, etc...
var columns = new[] {"Invoice_Id", "Software_Id", "Price", "Quantity", "Sum" }
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (columns.Contains(column.Name))
{
dt.Columns.Add();
}
}
foreach (DataGridViewRow row in dgv.Rows)
{
DataRow newRow = dt.NewRow();
foreach (string columnName in columns)
{
newRow[columnName] = row.Cells[columnName].Value
}
dt.Rows.Add(newRow);
}
return dt;
}
然后InsertDTtoDB
方法變為:
private void InsertDTtoDB(string ConnectionString, string TableName, DataGridView DGV)
{
DataTable dt = GetDataTableFromDGV(DGV);
using (SqlConnection cn = new SqlConnection(ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
// update the "DestinationCol[x]" values to the destination column names
copy.ColumnMappings.Add("Invoice_Id", "DestinationCol1");
copy.ColumnMappings.Add("Software_Id", "DestinationCol2");
copy.ColumnMappings.Add("Price", "DestinationCol3");
copy.ColumnMappings.Add("Quantity", "DestinationCol4");
copy.ColumnMappings.Add("Sum", "DestinationCol5");
copy.DestinationTableName = TableName;
copy.WriteToServer(dt);
}
}
}
要回答關於為什么將空行添加到數據庫的問題,我懷疑是因為 DataGridView 中有空值。 假設是這種情況,然后將 DataGridView 中的空值排除在添加到 DataTable 中。 我會關閉關鍵列之一,例如“Invoice_Id”; GetDataTableFromDGV
方法然后變為:
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
// assumes the columns in the DataGridView are named as follows:
var columns = new[] {"Invoice_Id", "Software_Id", "Price", "Quantity", "Sum" }
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (columns.Contains(column.Name))
{
dt.Columns.Add();
}
}
foreach (DataGridViewRow row in dgv.Rows)
{
// check if the row has a null "Invoice_Id" and exclude
if(row.Cells["Invoice_Id"] == null
{
continue;
}
DataRow newRow = dt.NewRow();
foreach (string columnName in columns)
{
newRow[columnName] = row.Cells[columnName].Value
}
dt.Rows.Add(newRow);
}
return dt;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.