1

I'm trying for the first time to use SqlBulkCopy. I have a table created this way:

IF NOT EXISTS(SELECT 1 FROM sys.tables 
              WHERE Name = N'DetectionLoggingTime' 
                AND Object_ID = Object_ID(N'dbo.DetectionLoggingTime'))
BEGIN
    PRINT N'Creating [dbo].[DetectionLoggingTime]...';

    CREATE TABLE [dbo].[DetectionLoggingTime]
    (
        [LogId]       INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
        [ScreeningId] BIGINT        NOT NULL,
        [Message]     NVARCHAR(255) NOT NULL,
        [Time]        BIGINT        NULL
    );
END

I am trying to insert values in this way:

public async Task Handle(DetectionLoggingIntegrationEvent @event)
{
    var dt = new DataTable();
    dt.Columns.Add("ScreeningId");
    dt.Columns.Add("Message");
    dt.Columns.Add("Time");

    @event.OperationTimePairs.ForEach(pair => dt.Rows.Add(@event.ScreeningId, pair.Key, pair.Value));

    using (var sqlBulk = new SqlBulkCopy(_configProvider.MyConnectionString))
    {
        sqlBulk.DestinationTableName = "DetectionLoggingTime";
        sqlBulk.WriteToServer(dt);
    }
}

My feeling is that the insertion is trying to insert the LogId which I would like it to be incremental and automatically generated by SQL Server. What am I doing wrong?

2 Answers 2

1

Found the solution, explicit column mappings are required:

public async Task Handle(DetectionLoggingIntegrationEvent @event)
{
    var dt = new DataTable();
    dt.Columns.Add("ScreeningId", typeof(long));
    dt.Columns.Add("Message");
    dt.Columns.Add("Time", typeof(long));

    @event.OperationTimePairs.ForEach(pair => dt.Rows.Add(@event.ScreeningId, pair.Key, pair.Value));

    using (var sqlBulk = new SqlBulkCopy(_configProvider.FdbConnectionString))
    {
        var mapping = new SqlBulkCopyColumnMapping("ScreeningId", "ScreeningId");
        sqlBulk.ColumnMappings.Add(mapping);

        mapping = new SqlBulkCopyColumnMapping("Message", "Message");
        sqlBulk.ColumnMappings.Add(mapping);

        mapping = new SqlBulkCopyColumnMapping("Time", "Time");
        sqlBulk.ColumnMappings.Add(mapping);

        sqlBulk.DestinationTableName = "DetectionLoggingTime";
        sqlBulk.WriteToServer(dt);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

That issue is often caused before the column type in the DataTable are not explicit.

By example, setting the column type might fix that error:

var dt = new DataTable();
dt.Columns.Add("ScreeningId", typeof(long));
dt.Columns.Add("Message");
dt.Columns.Add("Time", typeof(long));

More documentation about this issue here: https://sqlbulkcopy-tutorial.net/type-a-cannot-be-converted-to-type-b

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.