Encontrei três maneiras de resolver o problema.
Índices exclusivos no EntityFramework Core:
Primeira abordagem:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Entity>()
.HasIndex(p => new {p.FirstColumn , p.SecondColumn}).IsUnique();
}
A segunda abordagem para criar restrições exclusivas com o EF Core usando chaves alternativas.
Exemplos
Uma coluna:
modelBuilder.Entity<Blog>().HasAlternateKey(c => c.SecondColumn).HasName("IX_SingeColumn");
Várias colunas:
modelBuilder.Entity<Entity>().HasAlternateKey(c => new [] {c.FirstColumn, c.SecondColumn}).HasName("IX_MultipleColumns");
EF 6 e abaixo:
Primeira abordagem:
dbContext.Database.ExecuteSqlCommand(string.Format(
@"CREATE UNIQUE INDEX LX_{0} ON {0} ({1})",
"Entitys", "FirstColumn, SecondColumn"));
Essa abordagem é muito rápida e útil, mas o principal problema é que o Entity Framework não sabe nada sobre essas alterações!
Segunda abordagem:
Encontrei-a neste post, mas não tentei sozinha.
CreateIndex("Entitys", new string[2] { "FirstColumn", "SecondColumn" },
true, "IX_Entitys");
O problema dessa abordagem é o seguinte: Ele precisa do DbMigration, então o que você faz se não o possui?
Terceira abordagem:
acho que é a melhor, mas requer algum tempo para fazê-lo. Vou apenas mostrar a idéia por trás disso: neste link http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a,
você pode encontrar o código para anotação de dados chave exclusiva:
[UniqueKey] // Unique Key
public int FirstColumn { get; set;}
[UniqueKey] // Unique Key
public int SecondColumn { get; set;}
// The problem hier
1, 1 = OK
1 ,2 = NO OK 1 IS UNIQUE
O problema para esta abordagem; Como posso combiná-los? Eu tenho uma idéia para estender esta implementação da Microsoft, por exemplo:
[UniqueKey, 1] // Unique Key
public int FirstColumn { get; set;}
[UniqueKey ,1] // Unique Key
public int SecondColumn { get; set;}
Posteriormente, no IDatabaseInitializer, conforme descrito no exemplo da Microsoft, você pode combinar as chaves de acordo com o número inteiro especificado. Porém, uma coisa deve ser observada: se a propriedade exclusiva for do tipo string, você deverá definir o MaxLength.