Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bulk insert with nullable bool #676

Open
79it opened this issue Dec 15, 2022 · 0 comments
Open

Bulk insert with nullable bool #676

79it opened this issue Dec 15, 2022 · 0 comments

Comments

@79it
Copy link

79it commented Dec 15, 2022

I've come across an issue when trying to use InsertBulk with nullable bools saved as nullable bits in a SQL Server database.

If the first row of data sets a value (true or false) then subsequent nulls in the column are imported as expected.

However, if the first row's value is null, as soon as a subsequent row has a non-null value the following exception occurs:
Cannot change DataType of a column once it has data.

This happens In SqlBulkCopyHelper - in debug you can see that the DataType has been set as {Name = "Boolean" FullName = "System.Boolean"} and wants to be changed to {Name = "Int32" FullName = "System.Int32"}

This is where the exception is occurring.

                    if (newType != null && newType != typeof (DBNull))
                    {
                        table.Columns[i].DataType = newType;
                    }

As a temporary fix, I've made a copy of SqlBulkCopyHelper and made a tweak to BuildBulkInsertDataTable where it sets the column type.

I have replaced:

            foreach (var col in cols)
            {
                bulkCopy.ColumnMappings.Add(col.Value.MemberInfoKey, col.Value.ColumnName);
                table.Columns.Add(col.Value.MemberInfoKey, Nullable.GetUnderlyingType(col.Value.MemberInfoData.MemberType) ?? col.Value.MemberInfoData.MemberType);
            } 

with:

            foreach (var colValue in cols.Select(x => x.Value))
            {
                var dataType = Nullable.GetUnderlyingType(colValue.MemberInfoData.MemberType) ?? colValue.MemberInfoData.MemberType;
                if (dataType == typeof(bool))
                {
                    dataType = typeof(int);
                }

                bulkCopy.ColumnMappings.Add(colValue.MemberInfoKey, colValue.ColumnName);
                table.Columns.Add(colValue.MemberInfoKey, dataType);
            }

This works by forcing the type to int if it's a boolean.

Is there a better way to handle InsertBulk with nullable bools?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant