web-dev-qa-db-fra.com

Entity Framework Core ajoute un code de contrainte unique en premier

Je ne trouve pas le moyen d'ajouter une contrainte unique à mon attribut de champ

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 

 "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",
66
Vadim M

Sur EF core, vous ne pouvez pas créer d'index à l'aide d'annotations de données. Mais vous pouvez le faire à l'aide de l'API Fluent. 

Comme ceci 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: Indexes

147
Sampath

De même, si vous voulez créer des contraintes uniques sur plusieurs colonnes, vous pouvez simplement le faire (après @ Sampath link )

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; }
}
39

Solution pour EF Core

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})
    }
}

La table DB 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 de base EF

Aucune de ces méthodes ne fonctionnait pour moi dans .NET Core 2.2, mais j'ai pu adapter le code que j'avais pour définir une clé primaire différente afin de fonctionner à cette fin.

Dans l'exemple ci-dessous, je veux m'assurer que le champ OutletRef est unique:

public class ApplicationDbContext : IdentityDbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Outlet>()
                .HasIndex(o => new { o.OutletRef });
        }
    }

Cela ajoute l'index unique requis dans la base de données. Cependant, il ne permet pas de spécifier un message d'erreur personnalisé.

1
Robin Wilson

Le PO 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 IS possible, mais pas une fonctionnalité immédiate de l'équipe de base EF. 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 déjà posté ici

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
Justin Tubbs

Nous pouvons ajouter un index de clé unique en utilisant api fluide. Le code ci-dessous a fonctionné pour moi

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

    }
0
Kuldeep Singh

Pour quelqu'un qui essaie toutes ces solutions mais ne fonctionne pas, essayez celui-ci, cela a fonctionné pour moi

 protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<User>()
         .Property(t => t.Email)
        .HasColumnAnnotation(
    "Index",
    new IndexAnnotation(new IndexAttribute { IsUnique = true }));
    }
0
Shonie