SqlBulkCopy - Le nom de colonne donné ne correspond à aucune colonne de la source ou de la destination

c# sqlbulkcopy sql-server

Question

J'essaie d'utiliser SqlBulkCopy pour copier des données dans une table de base de données SQL, mais cela signifie (à tort) que les colonnes ne correspondent pas. Ils correspondent. Si j'utilise un point d'arrêt pour voir les noms des colonnes en cours de mappage, ils sont corrects. Le message d'erreur indique le nom de la colonne et il est correct.

Ceci est ma méthode. J'ai une méthode identique qui fonctionne et la seule différence est l' endroit où il obtient les noms de colonnes de. Les chaînes contenant les noms de colonne, cependant, sont EXACTEMENT identiques.

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

C'est la méthode de travail presque identique:

    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 cela vous aide, les noms de colonne sont: ACT_Code, ACT_Paid, ACT_Name, ACT_Terminal_Code, ACT_TCustom1, ACT_TCustom2. Ce sont exactement les mêmes dans la base de données elle-même. Je suis conscient que les mappages SqlBulkCopy sont sensibles à la casse et que les noms de colonne sont corrects.

C'est le message d'erreur:

Une exception non gérée du type 'System.InvalidOperationException' s'est produite dans System.Data.dll

Informations complémentaires: Le nom de colonne 'ACT_Code' donné ne correspond à aucune colonne de la source de données.

Espérons que je manque juste quelque chose d'évident ici, mais je suis bel et bien perdu.

Merci beaucoup.

EDIT: Pour toute personne ayant le même problème que moi, voici comment je l’ai corrigé.

Au lieu de faire de la méthode ManualMapImport() un quasi-clone de AutoMapImport() , je l'ai fait parcourir les colonnes du datatable et changer les noms, puis appelé AutoMapImport() avec le datatable modifié, éliminant le besoin d'essayer avec des cordes simples du tout.

Réponse populaire

Selon MSDN ( ici ), la méthode DataColumn.ToString() renvoie " La valeur Expression, si la propriété est définie; sinon, la propriété ColumnName. ".

J'ai toujours trouvé de toute façon que la méthode ToString() était mauvaise (de toute façon, elle peut changer en fonction de l'état / des conditions actuels), je vous recommande donc d'utiliser la propriété ColumnName , car c'est ce que vous essayez réellement de tirer de ToString() .


OK, à défaut de cela, je devrais alors deviner qu'il s'agit d'un problème de respect de la casse dans les noms des colonnes du fichier source de données, car SQLBulkCopy est très sensible à la casse, même si la base de données SQL ne l'est pas. Pour remédier à cela, je dirais que lorsque vous vérifiez si cette colonne existe, vous devez alors renvoyer / utiliser la chaîne réelle de la liste de colonnes du datatable lui-même, plutôt que d'utiliser la chaîne qui a été transmise. Cela devrait pouvoir être corrigé. toute différence de casse ou d’accent que votre routine ColumnsExist pourrait ignorer.



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