I am using the SqlBulkCopy
object to insert a couple million generated rows into a database. The only problem is that the table I am inserting to has an identity column. I have tried setting the SqlBulkCopyOptions
to SqlBulkCopyOptions.KeepIdentity
and setting the identity column to 0
's, DbNull.Value
and null
. None of which have worked. I feel like I am missing something pretty simple, if someone could enlighten me that would be fantastic. Thanks!
edit To clarify, I do not have the identity values set in the DataTable
I am importing. I want them to be generated as part of the import.
edit 2
Here is the code I use to create the base SqlBulkCopy
object.
SqlBulkCopy sbc = GetBulkCopy(SqlBulkCopyOptions.KeepIdentity);
sbc.DestinationTableName = LOOKUP_TABLE;
private static SqlBulkCopy GetBulkCopy(SqlBulkCopyOptions options =
SqlBulkCopyOptions.Default)
{
Configuration cfg = WebConfigurationManager.OpenWebConfiguration("/RSWifi");
string connString =
cfg.ConnectionStrings.ConnectionStrings["WifiData"].ConnectionString;
return new SqlBulkCopy(connString, options);
}
To have the destination table assign the identity, do not use the SqlBulkCopyOptions.KeepIdentity
option. Instead, don't map the identity from the source, and don't extract it from source to send through to SqlBulkCopy
.
Fill the ColumnMapping
of the BulkCopy
object and don't map the identity column. The identity column will be generated by the target database.
You have two options -
1 - use KeepIdentity
and preserve the source's Identity
values.
2 - Don't map the Identity
field. If you don't try to assign a value the target table will assign one automatically.
Yes, You are right using SqlBulkCopyOptions.KeepIdentity
option then bulkcopy writer doesn't think that what is you table structure this object write from start column, so for our need, I am doing in same way to preserve identity field in my table just you have to make a extra column in you datatable object with rest of your needful columns and pass null values to this column then table automatically handles Identity.
This is how I solved it in .NET Core (dt
is your datatable):
dt.Columns.Cast<DataColumn>().ForEach((c, i) => sqlBulkCopy.ColumnMappings.Add(c.ColumnName, i + 1));
You basically skip the identity (Id
) column by assigning your destination columns with an ordinal starting from 1 instead of 0.
Cause :- There were some empty rows in the excel at the end of the data, which possibly looks like blank rows. Bulk upload was trying to upload these blank rows into the table.
Solution :- Select only the rows which contains data - copy the data into the new sheet. Say you have your data in 'Sheet 1', move it to 'Sheet 2' and delete 'Sheet 1'.
In my case it turned out to be blank space inside the column name and in one of the columns I had accidently used hyphon (-) instead of underscore (_) in my SQL table. I replaced blank space and hyphon with underscore in the sql table and it fixed the problem.
来源:https://stackoverflow.com/questions/6651809/sqlbulkcopy-insert-with-identity-column