SqlBulkCopy – El nombre de columna dado no coincide con ninguna columna en el origen o destino

Estoy tratando de usar SqlBulkCopy para copiar datos en una tabla de base de datos SQL, pero (erróneamente) dice que las columnas no coinciden. Ellos coinciden. Si utilizo un punto de interrupción para ver los nombres de las columnas que se asignan, son correctas. El mensaje de error muestra el nombre de la columna y es correcto.

Este es mi método. Tengo un método idéntico que funciona y la única diferencia es de dónde obtiene los nombres de columna. Sin embargo, las cadenas que contienen los nombres de columna son EXACTAMENTE idénticas.

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

Este es el método de trabajo casi idéntico:

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

Si ayuda, los nombres de las columnas son: ACT_Code, ACT_Paid, ACT_Name, ACT_Terminal_Code, ACT_TCustom1, ACT_TCustom2. Estos son exactamente los mismos en la base de datos en sí. Soy consciente de que las asignaciones de SqlBulkCopy distinguen entre mayúsculas y minúsculas, y los nombres de las columnas son correctos.

Este es el mensaje de error:

Se produjo una excepción no controlada de tipo ‘System.InvalidOperationException’ en System.Data.dll

Información adicional: el nombre de columna dado ‘ACT_Code’ no coincide con ninguna columna en el origen de datos.

Espero que me esté perdiendo algo obvio aquí, pero estoy bien y verdaderamente perdido.

Muchas gracias.

EDITAR: Para cualquier persona que tenga el mismo problema que yo, así es como lo solucioné.

En lugar de hacer que el método ManualMapImport() sea ​​casi un clon de AutoMapImport() , lo hice recorrer las columnas de la tabla de datos y cambiar los nombres, luego se llamó AutoMapImport() con la fecha de modificación modificada, eliminando la necesidad de probar y mapear con cuerdas lisas en absoluto.

Según MSDN ( aquí ), el método DataColumn.ToString() devuelve ” El valor de Expresión, si la propiedad está establecida; de lo contrario, la propiedad ColumnName “.

De todos modos, siempre he encontrado que el método ToString() es torpe (puede cambiar según el estado o las condiciones actuales), por lo que recomiendo usar la propiedad ColumnName lugar, ya que eso es lo que realmente intentas eliminar de ToString() .


De acuerdo, si falla eso, tendré que adivinar que este es un problema con la distinción entre mayúsculas y minúsculas en los nombres de las columnas en la fuente de datos de origen, ya que SQLBulkCopy es muy sensible a las mayúsculas y minúsculas, incluso si el DB DB no lo es. Para abordar esto, diría que cuando verifica si esa columna existe, entonces debería devolver / usar la cadena real de la propia lista de columnas de la tabla de datos, en lugar de usar la cadena que se pasó. Esto debería poder arreglarlo. cualquier diferencia de caso o acento que su rutina ColumnsExist pueda estar ignorando.

Tuve el mismo problema … El mensaje puede parecer un poco confuso, ya que sugiere que no realizó la asignación correcta.

Para encontrar la raíz del problema, he decidido ir paso a paso para agregar columnas de tablas y llamar al método WriteToServer .

Suponiendo que tiene una asignación de columna válida, deberá garantizar lo siguiente entre la tabla de datos de origen y la tabla de destino:

  • Los tipos de columna y longitudes (!) Coinciden
  • Ha proporcionado un valor válido para cada columna de destino no vacía ( NOT NULL )

Si no controla los valores de la columna de identidad y desea que SQL Server haga este trabajo por usted, asegúrese de no especificar la opción SqlBulkCopyOptions.KeepIdentity . En este caso, tampoco agrega la columna de identidad a su fuente.

Esto debe ser todo para que su inserto a granel funcione. Espero eso ayude.