-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
I suspect there's a bug in CommandBatchPreparer.BatchCommands or maybe an incorrect assumption about database providers. When a modificationCommand cannot be added to the current batch, this method yield returns the current batch, then places this modificationCommand into a new batch, which resets the parameterNameGenerator:
batch = StartNewBatch(parameterNameGenerator, modificationCommand);
But this modificationCommand already has parameter names that were generated by the parameterNameGenerator before it was reset to 0. For example, if the current batch has 300 parameters and a command with 301st parameter could not be added, this command, with a parameter named "p300", will become the first command of the new batch. If this new batch can fit more parameters than the previous batch, then parameterNameGenerator will generate "p300" again, and ReaderModificationCommandBatch.CreateStoreCommand() will fail with an ArgumentException because of a parameter name collision in the parameterValues dictionary.
Perhaps other database providers are not as flexible, and a subsequent batch can never have more parameters than a previous batch and this problem never manifests. Our database provider dynamically calculates the number of statements and parameters that can fit in a batch, so it is possible for batches (even those made up of identical statements) to have a different number of statements and parameters.
Ideally the parameter names in the modificationCommand that didn't fit should be regenerated starting with "p0". I don't see an easy way to do that. Another solution would be to not reset the parameterNameGenerator when a new batch is created, but that's a bit wasteful.
Provider and version information
EF Core version: 3.1.x
Database provider: the one I'm working on