There are existing options for doing bulk insert into a single table with EF entities. Specifically, this SO question and using this class from David Browne.
In the case of trying to bulk insert rows into both a parent and child table, however, nothing jumps out as an option at that same level of convenience.
The ‘hacks’ I can think of (but I’m hoping there’s at least one better option out there) include:
- generate the PK’s and set the FK’s before insert (in this scenario, we know nothing else is inserting at the same time), then do the bulk inserts of both (turning off IDENTITY_INSERT during the parent insert if necessary)
- bulk insert (using the linked SO question’s approach) the parent rows, select them (enough columns to identify which parent row is which), generate child rows, bulk insert those
- generate the sql necessary to insert all the rows in a single batch, doing each parent and then all related children, using @@identity to fill in the FK for the child inserts
The ‘pregenerate PK values’ approach (I haven’t actually tried it) seems fine, but is fragile (requires no other inserts to at least parent during the operation) and depends on either an empty table or selecting max(pk)+1 beforehand.
Since SqlBulkCopy seems to be built around inserting a table at a time (like bcp), anything that still lets sql generate the PK/identity column would seem to be built around ‘dropping down’ to ado.net and building the sql.
Is there an option outside of ‘generate the tons of sql’ that I’m missing? If not, is there something out there that already generates the sql for mass-insert into related tables?
Thanks!!
The first rule of any foreign key constraint is that it must exist, as a primary key or unique constraint, in another table before inserted into the foreign key table.
This works great when you are adding a few rows at a time (traditional transaction processing environment). Howevere, you are trying to bulk insert into both at the same time. I’d term this as batch processing. Basically, the bulk update lock on the parent table is going to block the child table from reading it to check that the fk linkage is valid.
I’d say your 2 options would be 1.) leave the fk out entirely or 2.) Set the fk as nocheck before the bulk insert, then turn the check on after the bulk insert is complete with an alter table.