简体   繁体   中英

Sql bulkcopy error - The given ColumnMapping does not match up with any column in the source or destination

I am trying to sqlbulkcopy to my sql table. My source that is the datatable has three columns and destination table has four columns the first column being idendity column. The destination table generates the values when record is inserted to the database. I am gettting "The given ColumnMapping does not match up with any column in the source or destination" at the following line of code. sqlBulkCopy.WriteToServer(dtExcelData); I dont understand what is the problem.

The destination table datatypes are as follows

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);

            }

I used to have your problem.

First use this class (it's not mine. i found this a long time ago over the internet and modified a little) and second make sure you are filling the correct table.

 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


}

Example:

You have table (CAR) with 3 columns Color and Weight and one identity column let say ID.

Create this class:

  public class BulkCopyCar
{
    public string Color { get; set; }

    public string Weight{ get; set; }
 }

Fill BulkCopyCar:

 List<BulkCopyCar> bulkCopyCarList = new List<BulkCopyCar>();
            bulkCopyCarList.Add(new BulkCopyCar() { Color = "Red", Weight = 155 });
            bulkCopyCarList.Add(new BulkCopyCar() { Color = "Blue", Weight = 400 });

Insert in to database:

 BulkCopy.IdentityColumnName = "ID";
            BulkCopy.IdentityColumnType = "int";
            BulkCopy.BulkSqlInsert(bulkCopyCarList, "CAR", SQLConnectionString);

If you don't have identity column use just this line:

BulkCopy.BulkSqlInsert(bulkCopyCarList, "CAR", SQLConnectionString);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM