Indexes
An index is a separate schema object, even when it enforces uniqueness.
Examples use Classic and Fluent tabs. Your choice follows you through the manual.
Create and remove an index
Use an explicit name so the index can be inspected or removed later. Fluent Create.Index(name).OnTable(table).WithColumns(...) names each part explicitly and preserves column order. Append Unique(), Clustered(), IncludeColumns(...) or WithFilter(...). For an existing Index definition, use Create.Index(definition).OnTable(table); fully qualify the model type if System.Index is also in scope.
Classic
Database.AddIndex("Users", new DotNetProjects.Migrator.Framework.Index
{
Name = "IX_Users_Name", KeyColumns = new[] { "Name" }, Unique = false
});Fluent
migration.Create.Index("IX_Users_Name").OnTable("Users").WithColumns("Name");Inside Up() / BuildUp(MigrationBuilder migration)
Classic
Database.RemoveIndex("Users", "IX_Users_Name");Fluent
migration.Delete.Index("IX_Users_Name").FromTable("Users");Inside Up() / BuildUp(MigrationBuilder migration)
Provider options
Index definitions also expose IncludeColumns, FilterItems and Clustered. These options are provider-specific. Oracle rejects included and clustered index requests; SQLite reconstruction rejects existing index SQL with explicit COLLATE clauses. Preview handles simple indexes and rejects unsupported options.
Unique index or unique constraint?
Use UniqueConstraint for a table-level invariant and an Index with Unique for an index definition. Do not infer ownership from a generated name. SQLite RemoveAllIndexes preserves declared table UNIQUE constraints; remove those through the constraint APIs. Check query plans and data cardinality when choosing index keys.