SQL Server
Explicit keys, provider-specific indexes, transactional DDL and application locks.
Examples use Classic and Fluent tabs. Your choice follows you through the manual.
Select the provider
Use ProviderTypes.SqlServer with an open Microsoft.Data.SqlClient connection. Pass the intended default schema, commonly dbo. Historical SqlServer2005 is a separate alias with older type mappings. WholeSession transactions and DatabaseMigrationLock are available for SQL Server.
Name constraints explicitly
Column changes preserve explicit constraints and indexes. Add/remove uniqueness independently. For a nonclustered primary key on an existing compatible table use the dedicated API shown below. Review existing clustered indexes before changing key layout.
Classic
Database.AddPrimaryKeyNonClustered("PK_Users", "Users", "Id");Fluent
migration.Create.NonClusteredPrimaryKey("PK_Users").OnTable("Users").WithColumns("Id");Inside Up() / BuildUp(MigrationBuilder migration)
Indexes and SQL batches
Index definitions can express included/filter/cluster options where supported. The script APIs split standalone GO lines; raw ExecuteNonQuery/Execute.Sql does not. SQLCMD directives and GO repetition are rejected before executing script batches. Prefer scripts for client batch syntax and commands for parameterized statements.
Types and object names
Use TimeOnly for time values and TimeSpan for interval ticks. SqlServer2005 uses its older DATETIME precision behavior. Use separate quoting helpers for table and column names. A table rename leaves named constraints/indexes attached with their old names; assign distinct names when creating a replacement table.