310 votes

Entity Framework Core ajouter la contrainte unique code-first

Je ne trouve pas le moyen d'ajouter une contrainte unique à mon champ en utilisant un attribut :

public class User
{
    [Required]
    public int Id { get; set; }

    [Required]
    // [Index("IX_FirstAndSecond", 2, IsUnique = true)] not supported by core
    public string Email { get; set; }

    [Required]
    public string Password { get; set; }
}

J'utilise ces paquets :

 "Microsoft.EntityFrameworkCore": "1.0.1",
 "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
 "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1",
 "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",

0 votes

Des exemples d'Api fluente pour les index sont disponibles à l'adresse suivante learnentityframeworkcore.com/configuration/fluent-api/

546voto

Sampath Points 4405

Sur EF core, vous ne pouvez pas créer d'index en utilisant des annotations de données, mais vous pouvez le faire en utilisant l'API Fluent.

Comme ça, dans votre {Db}Context.cs :

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>()
        .HasIndex(u => u.Email)
        .IsUnique();
}

...ou si vous utilisez la surcharge avec le buildAction :

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>(entity => {
        entity.HasIndex(e => e.Email).IsUnique();
    });
}

Vous pouvez en savoir plus à ce sujet ici : Indices

1 votes

Merci beaucoup pour votre aide, c'est la bonne solution !

0 votes

Au cas où quelqu'un atterrirait ici à la recherche d'une solution qui fonctionne avec le schéma MS Identity, je suggère de définir la contrainte unique sur le champ NormalizedEmail, et non sur Email (de l'entité AspNetUsers). L'utilisation d'un cas différent pourrait ne pas violer la contrainte même s'il s'agit de la même adresse e-mail, en fonction des paramètres de collation de la base de données.

7 votes

Ce code ne fonctionne pas pour les colonnes de type string :( Existe-t-il un moyen d'ajouter une contrainte unique sur une colonne string ?

147voto

De même, si vous souhaitez créer des contraintes uniques sur plusieurs colonnes, vous pouvez simplement procéder de la manière suivante (en suivant les conseils de @Sampath). enlace )

class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasIndex(p => new { p.FirstName, p.LastName })
            .IsUnique(true);
    }
}

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

18voto

Solution pour le noyau EF

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Passport { get; set; }
}

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public ApplicationContext()
    {
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=efbasicsappdb;Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasAlternateKey(u => u.Passport);
        //or: modelBuilder.Entity<User>().HasAlternateKey(u => new { u.Passport, u.Name})
    }
}

Le tableau de la BD ressemblera à ceci :

CREATE TABLE [dbo].[Users] (
    [Id]       INT            IDENTITY (1, 1) NOT NULL,
    [Name]     NVARCHAR (MAX) NULL,
    [Passport] NVARCHAR (450) NOT NULL,
    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [AK_Users_Passport] UNIQUE NONCLUSTERED ([Passport] ASC)
);

Référence aux documents EF Core

16 votes

Selon les documents EF Core : If you just want to enforce uniqueness of a column then you want a unique index rather than an alternate key. In EF, alternate keys provide greater functionality than unique indexes because they can be used as the target of a foreign key.

0 votes

Référence au commentaire de bigworld12 : docs.microsoft.com/fr/us/ef/core/modeling/

6voto

Justin Tubbs Points 39

L'OP demande s'il est possible d'ajouter un attribut à une classe d'entité pour une clé unique. La réponse courte est que c'est possible, mais ce n'est pas une fonctionnalité prête à l'emploi de l'équipe EF Core. Si vous souhaitez utiliser un attribut pour ajouter des clés uniques à vos classes d'entités Entity Framework Core, vous pouvez faire ce que j'ai mis en ligne aquí

public class Company
{
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid CompanyId { get; set; }

    [Required]
    [UniqueKey(groupId: "1", order: 0)]
    [StringLength(100, MinimumLength = 1)]
    public string CompanyName { get; set; }

    [Required]
    [UniqueKey(groupId: "1", order: 1)]
    [StringLength(100, MinimumLength = 1)]
    public string CompanyLocation { get; set; }
}

0 votes

L'attribut [UniqueKey] est un attribut défini par Microsoft ? ou il faut le définir soi-même ?

0 votes

L'attribut [UniqueKey] est un attribut personnalisé que j'ai développé pour permettre l'ajout de clés uniques dans les classes d'entités .cs (et non par le biais de la méthode OnModelCreating() du DbContext).

4 votes

C'est génial. Pourriez-vous mettre le code de l'attribut personnalisé que vous avez développé ?!

3voto

Shonie Points 22

Pour ceux qui ont essayé toutes ces solutions sans succès, essayez celle-ci, elle a fonctionné pour moi.

protected override void OnModelCreating(ModelBuilder builder)
{

    builder.Entity<User>().Property(t => t.Email).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_EmailIndex") { IsUnique = true }));

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X