will
will

Reputation: 897

How do you check the columnmapping on a SqlBulkCopy?

I'm calling SqlBulkCopy.WriteToServer, passing in a datatable. The table has five columns, but I'm only trying to populate two columns per row.

public static void LoadLogFiles(SqlConnection connection, IEnumerable<LogFile> logFiles)
    {
        using (var bulkCopier = new SqlBulkCopy(connection))
        {
            bulkCopier.DestinationTableName = ConfigurationManager.AppSettings["DestinationTable"];
            var dt = BuildLogFileDataTable(logFiles);
            try
            {
                bulkCopier.WriteToServer(dt);
            }
            catch (Exception e)
            {
                throw new Exception("SqlBulkCopy failed.", e);
            }
        }
    }
    private static DataTable BuildLogFileDataTable(IEnumerable<LogFile> logFiles)
    {
        var logFileTable = new DataTable("LogFiles");

        var idColumn = new DataColumn();
        idColumn.DataType = Type.GetType("System.Int32");
        idColumn.ColumnName = "Id";
        logFileTable.Columns.Add(idColumn);

        var pathColumn = new DataColumn();
        pathColumn.DataType = Type.GetType("System.String");
        pathColumn.ColumnName = "Path";
        logFileTable.Columns.Add(pathColumn);

        var fileNameColumn = new DataColumn();
        fileNameColumn.DataType = Type.GetType("System.String");
        fileNameColumn.ColumnName = "FileName";
        logFileTable.Columns.Add(fileNameColumn);

        var successColumn = new DataColumn();
        successColumn.DataType = Type.GetType("System.Boolean");
        successColumn.ColumnName = "Success";
        logFileTable.Columns.Add(successColumn);

        var errorMessageColumn = new DataColumn();
        errorMessageColumn.DataType = Type.GetType("System.String");
        errorMessageColumn.ColumnName = "ErrorMessgae";
        logFileTable.Columns.Add(errorMessageColumn);

        foreach (var logFile in logFiles)
        {
            var row = logFileTable.NewRow();
            row["Path"] = logFile.Path;
            row["FileName"] = logFile.FileName;

            logFileTable.Rows.Add(row);
        }

        return logFileTable;
    }

The error I'm getting suggests that somewhere, a string is being cast into a bit, but the only bit I have is the Success column, which isn't being touched.

The exception message:"The given value of type String from the data source cannot be converted to type bit of the specified target column."

Here's the table I'm targeting:

CREATE TABLE [dbo].[LogFiles] (
[Id]           INT            IDENTITY (1, 1) NOT NULL,
[Path]         NVARCHAR (MAX) NULL,
[FileName]     NVARCHAR (MAX) NULL,
[Success]      BIT            NULL,
[ErrorMessgae] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.LogFiles] PRIMARY KEY CLUSTERED ([Id] ASC)
);

Anyway, any help you guys and gals could offer would be great.

Upvotes: 1

Views: 436

Answers (2)

Alejandro Serrano
Alejandro Serrano

Reputation: 36

Even if you dont fill all the columns, you're passing all the datatable to the bulk.The identity column Id is causing the index problem.

I suggest to bulk the data to a staging table and then copy to LogFiles with a T-SQL statement.

Upvotes: 2

MEdwin
MEdwin

Reputation: 2960

i had this problem before. I has to do with the order of the newly added columns. Make sure you add the new column is order of the base table using SetOrdinal.

logFileTable.Columns.Add(pathColumn).SetOrdinal(1);//for Path
logFileTable.Columns.Add(pathColumn).SetOrdinal(2);//for FileName

Upvotes: 1

Related Questions