index framework foreign first dataannotations data column code c# .net entity-framework entity-framework-6 fluent-interface

c# - foreign - Creación de índice único con la API de Entity Framework 6.1 con fluidez



unique entity framework core (6)

En la nueva versión de EF que es 6.2 , puede usar el método HasIndex :

modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique(true); modelBuilder.Entity<User>().HasIndex(user => user.UserName).IsUnique(true);

Actualización para EF Core:

modelBuilder.Entity<User>() .HasIndex(b => b.Email) .IsUnique(); modelBuilder.Entity<User>() .HasIndex(b => b.UserName) .IsUnique();

Microsoft Docs - EF Core Indexes

Tengo una columna "Nombre" que debe estar separada. Sin clave foránea ni nada de eso.

EF 6.1 finalmente admite la creación de tales índices a través de Anotaciones. Eso ya se ha discutido en SO. Pero parece que solo se puede hacer a través de anotaciones en las clases. ¿Cómo hago eso usando solo la API Fluent?

Algo como esto:

public class PersonConfiguration : EntityTypeConfiguration<Person> { public PersonConfiguration() { HasKey(p => p.Id); Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); //not possible? Index(p => p.Name).IsUnique(); //??? } }


Esta respuesta contiene solo información adicional ya que hay respuestas excelentes.

Si desea tener múltiples campos únicos en su índice, puede lograrlo agregando la propiedad Order . También debe asegurarse de usar el mismo nombre de índice en todas sus propiedades (consulte uniqueIndex continuación).

string uniqueIndex = "UN_TableName"; this.Property(t => t.PropertyOne) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute(uniqueIndex) { IsUnique = true, Order = 1 } ) ); this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation( new IndexAttribute(uniqueIndex) { IsUnique = true, Order = 2 } ) );

Ahora, digamos que también quiere un índice en PropertyTwo .

La forma incorrecta de hacerlo sería comenzar una nueva línea con this.Property(t => t.PropertyTwo) ya que CANCELARía su índice único.

Todos sus índices (índice y único) se deben definir al mismo tiempo. Esta sería la forma correcta de hacerlo:

this.Property(t => t.PropertyTwo) .HasColumnAnnotation( IndexAnnotation.AnnotationName, new IndexAnnotation(new[] { new IndexAttribute(), // This is the index new IndexAttribute(uniqueIndex) // This is the Unique made earlier { IsUnique = true, Order = 2 } } ) );

Finalmente, si también desea cambiar el orden de clasificación de su índice / único, puede ver:

¿Cómo agregar un índice en múltiples columnas con clasificación ASC / DESC usando la API Fluent? .


Para mí, usando MVC 5 y EF 6, el punto clave era especificar una longitud en la propiedad de cadena donde quería colocar el índice.

protected override void OnModelCreating(DbModelBuilder modelBuilder){ //More stuff modelBuilder.Entity<Device>().Property(c => c.Name).HasColumnType("nvarchar").HasMaxLength(50); modelBuilder.Entity<Device>().HasIndex(c => c.Name).IsUnique(true); }


Puede crear un índice único en su archivo de migración.

En el Administrador de paquetes:

  1. Habilitar migraciones
  2. Add-Migration InitialMigration

Esto creará un nuevo archivo en su carpeta Migrations que tiene marca de tiempo. La clase tendrá un método Arriba y Abajo que puede usar para crear el índice:

public override void Up() { // ... CreateIndex("tableName", "columnName", unique: true, name: "myIndex"); } public override void Down() { // ... DropIndex("tableName", "myIndex"); }

Para ejecutar la migración escriba Update-Database en el administrador de paquetes.

También puede agregar el índice como parte de la migración que también crea la tabla:

CreateTable( "dbo.Products", c => new { ProductId = c.Int(nullable: false, identity: true), ProductName = c.String(nullable: false, maxLength: 256), }) .Index(c => c.ProductName, name: "IX_Products_ProductName", unique: true) .PrimaryKey(t => t.ProductId);


Según la respuesta de Anatolii, este es un método de extensión para establecer índices únicos con más fluidez:

public static class MappingExtensions { public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration) { return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true })); } }

Uso:

modelBuilder .Entity<Person>() .Property(t => t.Name) .IsUnique();

Generará migración como:

public partial class Add_unique_index : DbMigration { public override void Up() { CreateIndex("dbo.Person", "Name", unique: true); } public override void Down() { DropIndex("dbo.Person", new[] { "Name" }); } }


NOTA: relevante para EF 6

Puede usar IndexAttribute como se mencionó pero con DataAnnotations Fluent API lugar de DataAnnotations que hará el truco:

modelBuilder .Entity<Person>() .Property(t => t.Name) .HasColumnAnnotation( "Index", new IndexAnnotation(new IndexAttribute("IX_Name") { IsUnique = true }));

Lamentablemente, no hay otra manera de crear índices únicos utilizando la Fluent API . Existe un problema abierto con respecto a esta característica: Restricciones únicas (Índices únicos)

ACTUALIZACIÓN: Entity Framework Core

En la última versión de EF Core puede confiar en la Fluent API para especificar índices sin trucos adicionales.
HasIndex permite definirlo:

modelBuilder .Entity<Person>() .HasIndex(x => x.Name);

Por lo tanto, retoma el objeto IndexBuilder , puede usarlo para otras configuraciones de índice (es decir, unicidad):

modelBuilder .Entity<Person>() .HasIndex(x => x.Name) .IsUnique();