C# SqlBulkCopy-给定的ColumnName与源或目标中的任何列都不匹配

C# SqlBulkCopy-给定的ColumnName与源或目标中的任何列都不匹配,c#,sql-server,sqlbulkcopy,C#,Sql Server,Sqlbulkcopy,我试图使用SqlBulkCopy将数据复制到SQL数据库表中,但它(错误地)表示列不匹配。他们确实相配。如果我使用断点查看映射列的名称,则它们是正确的。错误消息显示列的名称,并且是正确的 这是我的方法。我有一个相同的方法可以工作,唯一的区别是它从哪里获取列名。但是,包含列名的字符串完全相同 public static bool ManualMapImport(DataTable dataTable, string table) { if(dataTable !=

我试图使用SqlBulkCopy将数据复制到SQL数据库表中,但它(错误地)表示列不匹配。他们确实相配。如果我使用断点查看映射列的名称,则它们是正确的。错误消息显示列的名称,并且是正确的

这是我的方法。我有一个相同的方法可以工作,唯一的区别是它从哪里获取列名。但是,包含列名的字符串完全相同

    public static bool ManualMapImport(DataTable dataTable, string table)
    {
        if(dataTable != null)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlBulkCopy import = new SqlBulkCopy(connection);
            import.DestinationTableName = "[" + table + "]";
            foreach (string s in Global.SelectedColumns)
            {                    
            /* The s string variable here is the EXACT same as
               the c.ToString() in the other method below */

                if (ColumnExists(table, s))
                    import.ColumnMappings.Add(s, s); 
                else
                    return false;
            }

            connection.Open();
            import.WriteToServer(dataTable); //Error happens on this line
            connection.Close();

            return true;
        }
        else
        {
            return false;
        }
    }
这是几乎相同的工作方法:

    public static bool AutoMapImport(DataTable dataTable, string table)
    {
        if (dataTable != null)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlBulkCopy import = new SqlBulkCopy(connection);
            import.DestinationTableName = "[" + table + "]";           
            foreach (DataColumn c in dataTable.Columns)
            {
                if (ColumnExists(table, c.ToString()))
                    import.ColumnMappings.Add(c.ToString(), c.ToString());
                else
                    return false;
            }

            connection.Open();
            import.WriteToServer(dataTable);
            connection.Close();

            return true;
        }
        else
        {
            return false;
        }
    }
如果有帮助,列名是:ACT_代码、ACT_付费、ACT_名称、ACT_终端代码、ACT_TCustom1、ACT_TCustom2。这些在数据库本身中是完全相同的。我知道SqlBulkCopy映射是区分大小写的,并且列名确实是正确的

这是错误消息:

“System.InvalidOperationException”类型的未处理异常 发生在System.Data.dll中

其他信息:给定的列名称“ACT_代码”不匹配 数据源中的任意列

希望我只是错过了一些明显的东西,但我确实迷失了方向

非常感谢

编辑:对于任何碰巧和我有同样问题的人,下面是如何解决的 我修好了

与其使用
ManualMapImport()
方法,不如使用
AutoMapImport()
,我让它在数据表的列中循环 并更改名称,然后使用修改后的 datatable,无需在 全部

根据MSDN(),
DataColumn.ToString()
方法返回“如果设置了属性,则返回表达式值;否则返回ColumnName属性”

我总是发现
ToString()
方法无论如何都是不可靠的(可以根据当前状态/条件进行更改),因此我建议改用
ColumnName
属性,因为这正是您实际试图从
ToString()
中得到的



好的,如果失败了,那么我不得不猜测这是源数据表中列的名称区分大小写的问题,因为即使SQL DB不区分大小写,
SQLBulkCopy
也非常区分大小写。为了解决这个问题,我想说,当您检查该列是否存在时,您应该返回/使用datatable列列表本身中的实际字符串,而不是使用传入的任何字符串。这应该能够解决你的专栏作家例行程序可能忽略的任何大小写或重音差异。

我也有同样的问题。。。该消息可能有点误导,因为它表明您没有执行正确的映射

为了找到问题的根源,我决定一步一步地添加表列并调用
WriteToServer
方法

假设您有一个有效的列映射,则必须确保源
DataTable
和目标表之间存在以下情况:

  • 列类型和长度(!)不匹配
  • 您已为每个非空(
    notnull
    )目标列提供了有效值
如果您不控制标识列值,并且希望SQL Server为您执行此操作,请确保不要指定
SqlBulkCopyOptions.KeepIdentity
选项。在这种情况下,您也不会将identity列添加到源中


这应该是大容量插入工作的全部内容。希望有帮助。

谢谢你的提示,我会改变的,不过我确定。ToString()不是这里的问题。它是不使用.ToString()的顶级方法,该方法不起作用。DataColumn.ToString()正在工作。不幸的是,也不是这样。我已经直接从SQL中获取了它们,并用它们填充我的列表。什么是
Global.SelectedColumns
,它来自哪里/如何填充?我原以为是
DataGridView
中的
SelectedColumns
属性,但它不返回字符串。它只是一个
列表,里面填充了列名。它是通过查询数据库中所选表中的列列表并将其放入
全局.AllColumns
列表中来填充的,然后用户可以根据他们将使用应用程序打开的CSV文件选择所需的列,并按顺序排列。所选列被复制到
Global中。SelectedColumns
就是这个消息吗?它看起来不像我记得的那样..?还有,什么版本的SQL server?这就是复制和粘贴的确切消息。它是2014 express,但此应用程序将与各种版本一起使用。。。我的插入失败,因为在列[a]的源中,我的值为“ABCD”,而目标表中映射的列[a]为char(2)。