IndexAttribute is a data annotation attribute introduced in EF 6.1 that can be added to a property of a domain model to indicate that the property should participate in a store index. Entity Framework Code First Migrations uses this information to create indexes
in the relational database.
IndexAttribute allows indexes to be specified that span one ore more columns, and can be either named explicitly or have a name generated by convention. IndexAttribute allows indexes to be specified as explicitly unique or non-unique and/or clustered or non-clustered.
If these options are not specified explicitly then the default is to create non-unique, non-clustered indexes. Some databases may not support multiple clustered indexes on one table, in which case either the SQL generator or the database server may throw when
an attempt is made to specify such indexes.
A Code First convention (IndexAttributeConvention) is used to discover instances of IndexAttribute that have been applied to properties of the model. A model annotation (see below) is added for all the indexes on a given property.
Index information is represented in the Code First model through an annotation with the name “Index”. This annotation is always of type IndexAnnotation, which in turn collects together all IndexAttributes for a given column. Index annotations are stored in
the store model and target a column.
Index annotations can also be applied to columns using the HasColumnAnnotation fluent API.
Note that multiple properties can be mapped to a single column and a single property can be mapped to multiple columns. To handle this annotations are fanned out to all columns or combined to a single column as necessary. When multiple properties map to a single
column the same index annotation can be applied to any number of these properties. An exception is only thrown if multiple properties specify conflicting index information. For example, and exception will be thrown if one property defines a unique index called
“MyIndex” and another property defines “MyIndex” as non-unique.
Indexes that span multiple columns are specified by using the same name in multiple annotations on a given table.
Annotations are serialized to and from the EDMX to allow Migrations to determine when indexes are added, removed, or changed using the model differ. See
Code First Annotations
for details on how Code First annotations enable this.
The model differ has a native understanding of index annotations and hence does not issue the generic annotation information in operations. Instead index annotations for all columns on a table are combined into table-specific CreateIndex, DropIndex, and RenameIndex
Foreign key conventions
Migrations has always created indexes on foreign key columns. However, these indexes had no representation in the model which meant it was not possible to let Migrations know that the index had been removed or changed; Migrations would always assume that the
index existed in its default state.
Code First now includes a new convention (ForeignKeyIndexConvention) that will create indexes on FK columns using an index annotation. This maintains the same Migrations behavior as before while taking advantage of storing the index in the model.
The convention will only create an index if no explicit index is created for any of the FK columns. This means that the index created for FK columns can be customized by adding IndexAttribute to an FK property.
As of EF 6.1 IndexAttribute is contained in the EntityFramework assembly and shipped as part of the EntityFramework NuGet package. This is not ideal since it requires a reference to EntityFramework.dll in the domain assembly, but allows the attribute to be
shipped now until it can be moved into a more appropriate assembly. At that time EntityFramework.dll will type-forward to the new location.