Chaves exclusivas no Entity Framework 4

Um esquema de database existente possui chaves exclusivas, não primárias, e algumas foreign keys que dependem delas.

É possível definir chaves exclusivas, que não são chaves primárias, no Entity Framework v4? Como?

O Entity Framework 6.1 agora suporta uniques com Anotações de Dados e Fluent API.

Anotações de dados ( referência )

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

API fluente ( referência )

 public class MyContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder .Entity() .Property(t => t.MyUniqueProperty) .HasMaxLength(255) // for code-first implementations .HasColumnAnnotation( "Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }))); } } } 

Você precisa aplicar um índice e definir a propriedade exclusiva como true. Por padrão, os índices são não exclusivos de acordo com a documentação.

E também você precisa instalar o pacote NuGet do Entity Framework 6.1 em seu projeto para usar a nova API para índices.

Nota sobre implementações de primeiro código: Um VARCHAR(MAX) não pode fazer parte de uma restrição exclusiva. Você deve especificar o tamanho máximo como uma anotação de dados ou na API do Fluent.

Veja também este post no blog da MSDN: http://blogs.msdn.com/b/efdesign/archive/2011/03/09/unique-constraints-in-the-entity-framework.aspx . Em resumo, isso não é suportado na V4, embora a equipe da EF pareça ter planos de suportá-lo em versões futuras.

Eu me deparei com o mesmo problema há pouco tempo.

Eu fui dado um database com algumas tabelas (veja abaixo).

  public class ClinicDbContext : DbContext { public DbSet Users { get; set; } public DbSet Doctors { get; set; } public DbSet Patients { get; set; } public DbSet Secretarys { get; set; } public DbSet Diseases { get; set; } public DbSet Consultations { get; set; } public DbSet Administrators { get; set; } } 

A tabela Usuários foi descrita assim:

 public class User { [Key] public Guid UserId { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Name { get; set; } public string Surname { get; set; } public string IdentityCardNumber { get; set; } public string PersonalNumericalCode { get; set; } public DateTime DateOfBirth { get; set; } public string Address { get; set; } } 

Em seguida, fui solicitado a garantir que todos os atributos ” UserName ” fossem exclusivos. Como não há annotations para isso, eu tive que descobrir uma solução. E aqui está:

Primeiro, mudei minha class de contexto do database para ficar assim:

 public class ClinicDbContext : DbContext { public DbSet Users { get; set; } public DbSet Doctors { get; set; } public DbSet Patients { get; set; } public DbSet Secretarys { get; set; } public DbSet Diseases { get; set; } public DbSet Consultations { get; set; } public DbSet Administrators { get; set; } public class Initializer : IDatabaseInitializer { public void InitializeDatabase(ClinicDbContext context) { if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false)) { if (context.Database.Exists()) { context.Database.Delete(); } context.Database.Create(); context.Database.ExecuteSqlCommand("CREATE INDEX IX_Users_UserName ON dbo.Users ( UserName )"); } } } } 

A parte importante de cima é o comando sql que altera a tabela impondo um índice exclusivo em nossa coluna desejada -> UserName no nosso caso.

Este método pode ser chamado da class principal, por exemplo:

 class Program { static void Main(string[] args) { Database.SetInitializer(new ClinicDbContext.Initializer()); using (var ctx = new ClinicDbContext()) { Console.WriteLine("{0} products exist in the database.", ctx.Users.Count()); } Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } 

O problema final, que ocorreu ao tentar executar a class Program, foi o seguinte: a coluna na tabela é de um tipo inválido para uso como coluna-chave em um índice.

Para resolver esse problema, acabei de adicionar uma anotação [MaxLength (250)] para o atributo UserName.

Aqui está como a class User aparece no final:

 public class User { [Key] public Guid UserId { get; set; } [MaxLength(250)] public string UserName { get; set; } public string Password { get; set; } public string Name { get; set; } public string Surname { get; set; } public string IdentityCardNumber { get; set; } public string PersonalNumericalCode { get; set; } public DateTime DateOfBirth { get; set; } public string Address { get; set; } } 

Espero que isso resolva o seu problema também!

Eu tentei definir as seguintes tabelas:

  • Pedidos [Id (primário, identidade), ClientName, FriendlyOrderNum (exclusivo)]
  • OrderItems [Id (primário, identidade), FriendlyOrderNum (exclusivo), ItemName]

E um mapeamento de chave estrangeira de OrderItems.FriendlyOrderNum (Mant) para Orders.FriendlyOrderNum (one).

Se chaves únicas não primárias forem possíveis, o seguinte SSDL deverá funcionar:

                                      

Não faz. Também não há possibilidade de adicionar mais elementos em um .

Minha conclusão é que chaves exclusivas não primárias não são suportadas no EF 4.

Você pode usar a validação de DataAnnotations também.

Eu criei essa class ( UniqueAttribute ), que herda ValidationAttribute e, quando aplicada a uma propriedade, os valores dessa coluna serão recuperados e validados, durante a validação.

Você pode pegar o código bruto daqui .

    Intereting Posts