primary name framework foreign dataannotations data column annotation data-annotations entity-framework-4.3

data annotations - name - Primera columna única del código de Entity Framework



entity framework foreign key (5)

Desde su código, resulta evidente que usa POCO. No es necesario tener otra clave: puede agregar un índice como lo sugiere .
Si usa la API Fluent en lugar de atribuir la propiedad UserName, la anotación de la columna debería verse así:

this.Property(p => p.UserName) .HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } } ));

Esto creará la siguiente secuencia de comandos SQL:

CREATE UNIQUE NONCLUSTERED INDEX [Index] ON [dbo].[Users] ( [UserName] ASC ) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY]

Si intenta insertar varios usuarios con el mismo nombre de usuario, obtendrá una DbUpdateException con el siguiente mensaje:

Cannot insert duplicate key row in object ''dbo.Users'' with unique index ''Index''. The duplicate key value is (...). The statement has been terminated.

Nuevamente, las anotaciones de columna no están disponibles en Entity Framework antes de la versión 6.1.

Estoy usando Entity Framework 4.3 y usando Code Fist.

Tengo una clase

public class User { public int UserId{get;set;} public string UserName{get;set;} }

¿Cómo le digo a Entity Framework que UserName tiene que ser único al crear la tabla de la base de datos? Preferiría usar anotaciones de datos en lugar de archivo de configuración si es posible.


EF no admite columnas únicas, excepto las claves. Si está utilizando EF Migrations, puede forzar a EF a crear un índice único en la columna UserName (en el código de migración, no mediante ninguna anotación), pero la exclusividad se aplicará solo en la base de datos. Si intentas guardar el valor duplicado, deberás atrapar la excepción (violación de la restricción) disparada por la base de datos.


En Entity Framework 6.1+ puede usar este atributo en su modelo:

[Index(IsUnique=true)]

Puedes encontrarlo en este espacio de nombres:

using System.ComponentModel.DataAnnotations.Schema;

Si su campo de modelo es una cadena, asegúrese de que no esté configurado como nvarchar (MAX) en SQL Server o verá este error con el código de Entity Framework First:

La columna ''x'' en la tabla ''dbo.y'' es de un tipo que no es válido para usar como una columna clave en un índice.

La razón es por esto:

SQL Server conserva el límite de 900 bytes para el tamaño total máximo de todas las columnas de clave de índice ".

(desde: http://msdn.microsoft.com/en-us/library/ms191241.aspx )

Puede resolver esto estableciendo una longitud de cadena máxima en su modelo:

[StringLength(450)]

Su modelo se verá así ahora en EF CF 6.1+:

public class User { public int UserId{get;set;} [StringLength(450)] [Index(IsUnique=true)] public string UserName{get;set;} }

Actualizar:

si usas Fluent:

public class UserMap : EntityTypeConfiguration<User> { public UserMap() { // .... Property(x => x.Name).IsRequired().HasMaxLength(450).HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } })); } }

y uso en su modelBuilder:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { // ... modelBuilder.Configurations.Add(new UserMap()); // ... }

Actualización 2

para EntityFrameworkCore vea también este tema: https://github.com/aspnet/EntityFrameworkCore/issues/1698

Actualización 3

para EF6.2 ver: https://github.com/aspnet/EntityFramework6/issues/274


Solución para EF4.3

Nombre de usuario único

Agregar anotación de datos sobre la columna como:

[Index(IsUnique = true)] [MaxLength(255)] // for code-first implementations public string UserName{get;set;}

ID único , he agregado la decoración [Key] sobre mi columna y listo. La misma solución que se describe aquí: https://msdn.microsoft.com/en-gb/data/jj591583.aspx

ES DECIR:

[Key] public int UserId{get;set;}

Respuestas alternativas

usando la anotación de datos

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Column("UserId")]

usando mapeo

mb.Entity<User>() .HasKey(i => i.UserId); mb.User<User>() .Property(i => i.UserId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) .HasColumnName("UserId");


Tenga en cuenta que en Entity Framework 6.1 (actualmente en versión beta) se admitirá IndexAttribute para anotar las propiedades del índice, lo que automáticamente dará como resultado un índice (único) en sus primeras migraciones de código.