Skip to content

Add DATA_COMPRESSION support for primary keys and unique constraints#38434

Open
m-x-shokhzod wants to merge 1 commit into
dotnet:mainfrom
m-x-shokhzod:feat/sqlserver-key-data-compression
Open

Add DATA_COMPRESSION support for primary keys and unique constraints#38434
m-x-shokhzod wants to merge 1 commit into
dotnet:mainfrom
m-x-shokhzod:feat/sqlserver-key-data-compression

Conversation

@m-x-shokhzod

@m-x-shokhzod m-x-shokhzod commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

SQL Server PRIMARY KEY / UNIQUE constraints accept WITH (DATA_COMPRESSION = ...), just like indexes do (#30408 added it for indexes). This adds first-class support for configuring it on keys, mirroring the existing index DATA_COMPRESSION and key FILLFACTOR support.

modelBuilder.Entity<Blog>().HasKey(b => b.Id).UseDataCompression(DataCompressionType.Page);
modelBuilder.Entity<Blog>().HasAlternateKey(b => b.Code).UseDataCompression(DataCompressionType.Row);

produces:

CONSTRAINT [PK_Blog] PRIMARY KEY ([Id]) WITH (DATA_COMPRESSION = PAGE)
CONSTRAINT [AK_Blog_Code] UNIQUE ([Code]) WITH (DATA_COMPRESSION = ROW)

SqlServerAnnotationProvider.For(IUniqueConstraint) attaches the annotation; the base generator's PrimaryKeyConstraint/UniqueConstraint already call the shared IndexOptions, which already emits DATA_COMPRESSION, so the migrations generator itself is unchanged. As with the index case, DATA_COMPRESSION is not reverse-engineered.

Fixes #33145

Fixes dotnet#33145.

SQL Server PRIMARY KEY / UNIQUE constraints accept WITH (DATA_COMPRESSION = ...)
just like indexes do. This adds first-class support, mirroring the existing index
DATA_COMPRESSION and key FILLFACTOR features:

- UseDataCompression on KeyBuilder / KeyBuilder<TEntity> / IConventionKeyBuilder
  (plus CanSetDataCompression), and Get/SetDataCompression on the key metadata.
- SqlServerAnnotationProvider attaches the annotation to the unique constraint.
  The shared IndexOptions already emits DATA_COMPRESSION for AddPrimaryKey /
  AddUniqueConstraint operations, so the migrations generator needs no change.
- Fluent-API, runtime-annotation, and runtime-model code generation handling.

As with the index case, DATA_COMPRESSION is not reverse-engineered.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class SQL Server DATA_COMPRESSION configuration support for primary keys and unique constraints, aligning key/constraint configuration with existing index option support and enabling migrations to emit WITH (DATA_COMPRESSION = ...) for constraints.

Changes:

  • Added key-level APIs (UseDataCompression, Get/SetDataCompression) and wired them into the SQL Server annotation/codegen pipeline.
  • Updated SqlServerAnnotationProvider.For(IUniqueConstraint) to surface key DATA_COMPRESSION as a constraint annotation so migrations SQL can emit it.
  • Added unit and functional test coverage for configuring and generating SQL for compressed PK/AK constraints.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/EFCore.SqlServer.Tests/Metadata/SqlServerBuilderExtensionsTest.cs Adds tests verifying UseDataCompression can be set on keys (generic and non-generic).
test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs Adds migration SQL assertion for DATA_COMPRESSION on PK and unique constraints.
src/EFCore.SqlServer/Metadata/Internal/SqlServerAnnotationProvider.cs Emits DataCompression annotation for IUniqueConstraint based on mapped key configuration.
src/EFCore.SqlServer/Metadata/Conventions/SqlServerRuntimeModelConvention.cs Strips DataCompression from runtime model annotations for keys (consistent with other key facets).
src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs Introduces key extension APIs for DataCompression (including store-object overload).
src/EFCore.SqlServer/Extensions/SqlServerKeyBuilderExtensions.cs Adds fluent configuration (UseDataCompression) and convention APIs for keys.
src/EFCore.SqlServer/EFCore.SqlServer.baseline.json Updates API baseline to include the new public extension methods.
src/EFCore.SqlServer/Design/Internal/SqlServerCSharpRuntimeAnnotationCodeGenerator.cs Removes DataCompression from runtime annotation emission for keys/unique constraints.
src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs Emits .UseDataCompression(...) fluent API for key annotations when scaffolding code.

Comment on lines +179 to +182
if (key.GetDataCompression() is { } dataCompression)
{
yield return new Annotation(SqlServerAnnotationNames.DataCompression, dataCompression);
}
/// <returns>The <see cref="ConfigurationSource" /> for whether the key uses the fill factor.</returns>
public static ConfigurationSource? GetFillFactorConfigurationSource(this IConventionKey key)
=> key.FindAnnotation(SqlServerAnnotationNames.FillFactor)?.GetConfigurationSource();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modify AreCompatibleForSqlServer to check that the configured values that end up on the same table key are not conflicting

/// <param name="key">The key.</param>
/// <param name="dataCompression">The value to set.</param>
public static void SetDataCompression(this IMutableKey key, DataCompressionType? dataCompression)
=> key.SetAnnotation(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use SetOrRemoveAnnotation. Also below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQL Server Primary key/Unique contrainst index with options DATA_COMPRESSION

3 participants