Sql bulkcopy error - Le ColumnMapping donné ne correspond à aucune colonne de la source ou de la destination

asp.net asp.net-mvc c# npoi sqlbulkcopy

Question

J'essaye de sqlbulkcopy à ma table de SQL. Mon source qui est le datatable a trois colonnes et la table de destination a quatre colonnes, la première colonne étant la colonne idendity. La table de destination génère les valeurs lorsque l'enregistrement est inséré dans la base de données. J'obtiens "Le ColumnMapping donné ne correspond à aucune colonne de la source ou de la destination" à la ligne de code suivante. sqlBulkCopy.WriteToServer (dtExcelData); Je ne comprends pas quel est le problème.

Les types de données de la table de destination sont les suivants

Id (int), AccountNumber (varchar 9), montant (décimal 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);

            }

Réponse populaire

J'ai eu ton problème.

Commencez par utiliser cette classe (ce n’est pas la mienne. Je l’ai trouvée il y a longtemps sur Internet et en ai modifié un peu), puis assurez-vous de remplir le bon tableau.

 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


}

Exemple:

Vous avez une table (CAR) avec 3 colonnes Couleur et Poids et une colonne d’identité disons ID.

Créer cette classe:

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

    public string Weight{ get; set; }
 }

Remplir BulkCopyCar:

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

Insérer dans la base de données:

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

Si vous n'avez pas de colonne d'identité, utilisez uniquement cette ligne:

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


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi