Я пытаюсь выполнить sqlbulkcopy в моей таблице sql. Мой источник, который является datatable, имеет три столбца, а таблица назначения имеет четыре столбца, первый столбец которых является столбцом idendity. Таблица назначения генерирует значения, когда запись вставляется в базу данных. Я получаю «Данные ColumnMapping не соответствуют ни одному столбцу в источнике или получателе» в следующей строке кода. sqlBulkCopy.WriteToServer (dtExcelData); Я не понимаю, в чем проблема.
Типы данных таблицы назначения следующие.
Id (int), AccountNumber (varchar 9), Amount (decimal 11,2), Sedol (nvarchar 30)
XSSFWorkbook xssfwb;
using (FileStream file = new FileStream(excelPath, FileMode.Open, FileAccess.Read))
{
xssfwb = new XSSFWorkbook(file);
}
var sheet = xssfwb.GetSheetAt(0); // Change this to the worksheet you want to import.
var rows = sheet.GetRowEnumerator();
var dtExcelData = new DataTable();
var linenumber = 0;
DataRow dr;
dtExcelData.Columns.AddRange(new DataColumn[3] {
new DataColumn("AccountNumber", typeof(string)),
new DataColumn("Amount", typeof(decimal)),
new DataColumn("Sedol",typeof(string)) });
while (rows.MoveNext())
{
IRow row = (XSSFRow)rows.Current;
linenumber++;
row.GetCell(4).SetCellType(CellType.Numeric);
if (row.GetCell(0) != null)
{
dr = dtExcelData.NewRow();
dr["AccountNumber"] = row.GetCell(1).ToString();
//dr["Amount"] = decimal.Parse(row.GetCell(4).ToString());
dr["Amount"] = (decimal)row.GetCell(4).NumericCellValue;
dr["Sedol"] = row.GetCell(11).ToString();
dtExcelData.Rows.Add(dr);
}
}
DealingContext.ExecuteCommand("TRUNCATE TABLE [dbDealing].[MESSAGING].[Rebate]");
//Set the database table name
//using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(DealingContext.Connection.ConnectionString,SqlBulkCopyOptions.KeepIdentity))
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(DealingContext.Connection.ConnectionString))
{
sqlBulkCopy.DestinationTableName = "[dbDealing].[MESSAGING].[Rebate]";
//[OPTIONAL]: Map the Excel columns with that of the database table
sqlBulkCopy.ColumnMappings.Add("AccountNumber", "Owning Account ID");
sqlBulkCopy.ColumnMappings.Add("Amount", "Amount");
sqlBulkCopy.ColumnMappings.Add("Sedol", "Related Asset Identifier value");
sqlBulkCopy.WriteToServer(dtExcelData);
}
У меня была твоя проблема.
Сначала используйте этот класс (это не мое. Я нашел это давно в Интернете и немного изменил), а во-вторых, убедитесь, что вы заполняете правильную таблицу.
public static class BulkCopy
{
public static DataTable ToDataTable<T>(List<T> data)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
if (IdentityColumnName != null)
{
if (IdentityColumnType == "int")
table.Columns.Add(IdentityColumnName, typeof(Int32));
else if (IdentityColumnType == "string")
table.Columns.Add(IdentityColumnName, typeof(string));
}
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
if (IdentityColumnName != null)
{
object[] values = new object[props.Count + 1];
foreach (T item in data)
{
for (int i = 1; i < values.Length; i++)
{
values[i] = props[i - 1].GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(values);
}
}
else
{
object[] values = new object[props.Count];
foreach (T item in data)
{
int i = 0;
for (i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(values);
}
}
return table;
}
public static void BulkSqlInsert<T>(List<T> list, string tableName,string connectionString)
{
if (list == null)
throw new Exception("List of " + typeof(T).ToString() + " is null!");
BulkCopy.BulkSqlInsert(BulkCopy.ToDataTable<T>(list), tableName, connectionString);
}
public static void BulkSqlInsert(DataTable dt, string tableName, string connectionString)
{
if (dt.Rows.Count == 0)
return;
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlBulkCopy bulkCopy =
new SqlBulkCopy
(
connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
bulkCopy.DestinationTableName = tableName;
connection.Open();
bulkCopy.WriteToServer(dt);
connection.Close();
}
}
public static string IdentityColumnName { get; set; }
public static string IdentityColumnType { get; set; }//string or int
}
Пример:
У вас есть таблица (CAR) с 3 столбцами Цвет и вес и один столбец идентификатора, пусть говорят ID.
Создайте этот класс:
public class BulkCopyCar
{
public string Color { get; set; }
public string Weight{ get; set; }
}
Заполнить BulkCopyCar:
List<BulkCopyCar> bulkCopyCarList = new List<BulkCopyCar>();
bulkCopyCarList.Add(new BulkCopyCar() { Color = "Red", Weight = 155 });
bulkCopyCarList.Add(new BulkCopyCar() { Color = "Blue", Weight = 400 });
Вставить в базу данных:
BulkCopy.IdentityColumnName = "ID";
BulkCopy.IdentityColumnType = "int";
BulkCopy.BulkSqlInsert(bulkCopyCarList, "CAR", SQLConnectionString);
Если у вас нет столбца идентификатора, используйте только эту строку:
BulkCopy.BulkSqlInsert(bulkCopyCarList, "CAR", SQLConnectionString);