Estoy usando Entity Framework 5.0 Code First;
public class Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string EntityId { get; set;}
public int FirstColumn { get; set;}
public int SecondColumn { get; set;}
}
Quiero hacer la combinación entre FirstColumn
y SecondColumn
como única.
Ejemplo:
Id FirstColumn SecondColumn
1 1 1 = OK
2 2 1 = OK
3 3 3 = OK
5 3 1 = THIS OK
4 3 3 = GRRRRR! HERE ERROR
¿Hay alguna manera de hacerlo?
entity-framework
ef-code-first
constraints
multiple-columns
unique-key
Bassam Alugili
fuente
fuente
Encontré tres formas de resolver el problema.
Índices únicos en EntityFramework Core:
Primer enfoque:
El segundo enfoque para crear restricciones únicas con EF Core mediante el uso de claves alternativas.
Ejemplos
Una columna:
Múltiples columnas:
EF 6 y abajo:
Primer enfoque:
¡Este enfoque es muy rápido y útil, pero el problema principal es que Entity Framework no sabe nada sobre esos cambios!
Segundo enfoque:
lo encontré en esta publicación pero no lo intenté solo.
El problema de este enfoque es el siguiente: necesita DbMigration, ¿qué debe hacer si no lo tiene?
Tercer enfoque:
creo que este es el mejor, pero requiere algo de tiempo para hacerlo. Simplemente le mostraré la idea detrás de esto: en este enlace http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a puede encontrar el código para una anotación de datos clave única:
El problema para este enfoque; ¿Cómo puedo combinarlos? Tengo una idea para extender esta implementación de Microsoft, por ejemplo:
Más adelante en el IDatabaseInitializer como se describe en el ejemplo de Microsoft, puede combinar las claves de acuerdo con el entero dado. Sin embargo, hay que tener en cuenta una cosa: si la propiedad única es de tipo cadena, debe establecer MaxLength.
fuente
CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})
:? (ver BOL )Si usa Code-First , puede implementar una extensión personalizada HasUniqueIndexAnnotation
Luego úsalo así:
Lo que dará como resultado esta migración:
Y finalmente terminan en la base de datos como:
fuente
this.Property(t => t.Email)
), ¿qué es esa clase que contiene? (es decir, qué esthis
)EntityTypeConfiguration<T>
Necesita definir una clave compuesta.
Con anotaciones de datos se ve así:
También puede hacer esto con modelBuilder al anular OnModelCreating especificando:
fuente
La respuesta de niaher que indica que para usar la API fluida que necesita una extensión personalizada puede haber sido correcta al momento de la escritura. Ahora puede (EF core 2.1) usar la API fluida de la siguiente manera:
fuente
Completar la respuesta @chuck para usar índices compuestos con claves foráneas .
Debe definir una propiedad que contendrá el valor de la clave externa. Luego puede usar esta propiedad dentro de la definición del índice.
Por ejemplo, tenemos compañía con empleados y solo tenemos una restricción única en (nombre, compañía) para cualquier empleado:
Ahora el mapeo de la clase Empleado:
Tenga en cuenta que también usé la extensión @niaher para anotaciones de índice únicas.
fuente
En la respuesta aceptada por @chuck, hay un comentario que dice que no funcionará en el caso de FK.
funcionó para mí, caso de EF6 .Net4.7.2
fuente
Supongo que siempre quiere
EntityId
ser la clave principal, por lo que reemplazarla por una clave compuesta no es una opción (solo porque las claves compuestas son mucho más complicadas de trabajar y porque no es muy sensato tener claves primarias que también tengan significado en la lógica de negocios).Lo menos que debe hacer es crear una clave única en ambos campos en la base de datos y verificar específicamente las excepciones de violación de clave única al guardar los cambios.
Además, podría (debería) verificar valores únicos antes de guardar los cambios. La mejor manera de hacerlo es mediante una
Any()
consulta, ya que minimiza la cantidad de datos transferidos:Tenga en cuenta que este control solo nunca es suficiente. Siempre hay algo de latencia entre la verificación y la confirmación real, por lo que siempre necesitará la restricción única + manejo de excepciones.
fuente
Recientemente se agregó una clave compuesta con la singularidad de 2 columnas utilizando el enfoque que recomienda 'chuck', gracias @chuck. Solo este enfoque me pareció más limpio:
fuente