Feature | Add SqlBulkCopyOptions.CacheMetadata flag #3939
Feature | Add SqlBulkCopyOptions.CacheMetadata flag #3939samsharma2700 merged 19 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new SqlBulkCopyOptions.CacheMetadata flag to optimize repeated bulk copy operations to the same destination table by caching metadata after the first query, thus eliminating redundant metadata discovery queries on subsequent WriteToServer calls. This addresses issue #3627 where metadata queries were executed multiple times per operation, causing significant performance degradation in high-frequency bulk insert scenarios.
Changes:
- Adds new
CacheMetadataenum value toSqlBulkCopyOptions(bit 7) - Implements metadata caching logic in
SqlBulkCopywith automatic invalidation on table name changes - Adds public
InvalidateMetadataCache()method for manual cache invalidation - Includes comprehensive test coverage in both functional and manual test suites
- Provides XML documentation for the new API members
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopyOptions.cs | Adds CacheMetadata enum value (1 << 7) |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs | Implements caching logic with fields, cache check, cache storage, invalidation method, and dispose cleanup |
| src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBulkCopyCacheMetadataTest.cs | Adds unit tests for flag values, combinations, and API methods |
| src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CacheMetadata.cs | Adds integration tests for caching behavior, invalidation, destination changes, DataTable support, and option combinations |
| src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/SqlBulkCopyTest.cs | Wires up the new manual tests |
| src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj | Adds CacheMetadata.cs to project and introduces an unrelated project reference change |
| doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyOptions.xml | Documents CacheMetadata option with warnings about schema changes |
| doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml | Documents InvalidateMetadataCache method |
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/SqlBulkCopyTest.cs
Show resolved
Hide resolved
...crosoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopyOptions.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CacheMetadata.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CacheMetadata.cs
Outdated
Show resolved
Hide resolved
…amsharma2700/sqlbulkcopy_metadata_optimization
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CacheMetadata.cs
Show resolved
Hide resolved
…amsharma2700/sqlbulkcopy_metadata_optimization
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs:3262
ResetWriteToServerGlobalVariablessets_sqlDataReaderRowSource = null;twice. This looks like an accidental duplicate assignment and may be masking a missing reset of a different field. Remove the duplicate (or reset the intended field) to keep the state reset logic clear.
_rowSourceType = ValueSourceType.Unspecified;
_sqlDataReaderRowSource = null;
_sqlDataReaderRowSource = null;
}
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
paulmedynski
left a comment
There was a problem hiding this comment.
I've reviewed the code and some of the tests. We can discuss my comments before I review the remainder of the tests.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopyOptions.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBulkCopyCacheMetadataTest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBulkCopyCacheMetadataTest.cs
Outdated
Show resolved
Hide resolved
...soft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBulkCopyCacheMetadataTest.cs
Outdated
Show resolved
Hide resolved
…amsharma2700/sqlbulkcopy_metadata_optimization
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs
Show resolved
Hide resolved
Codecov Report✅ All modified and coverable lines are covered by tests.
Additional details and impacted files@@ Coverage Diff @@
## main #3939 +/- ##
===========================================
- Coverage 75.22% 64.56% -10.66%
===========================================
Files 266 282 +16
Lines 42932 65985 +23053
===========================================
+ Hits 32294 42605 +10311
- Misses 10638 23380 +12742
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Description
Add SqlBulkCopyOptions.CacheMetadata to skip redundant metadata queries on repeated WriteToServer calls.
Issue
SqlBulkCopy executes a metadata discovery query against the destination table on every WriteToServer call, even when the same instance is used repeatedly for the same table. This query (which retrieves column types, collations, and encryption metadata) adds a network roundtrip that's unnecessary when the schema hasn't changed.
Related issue: #3627
Solution
Add a new opt-in flag
SqlBulkCopyOptions.CacheMetadatathat caches the metadata result after the first query and reuses it for subsequentWriteToServercalls to the same table.Usage
Behavior
Why Opt-In
The metadata query provides schema information used by the TDS protocol. Caching assumes the destination table schema won't change between calls. Making this opt-in ensures
backwards compatibility and puts the responsibility for schema stability on the caller.
Changes
Testing
Build/Tests are passing.