Entity Framework Core benzersiz kısıtlama kodu ekler


173

Özniteliği kullanarak alanıma benzersiz bir sınırlama eklemenin bir yolunu bulamıyorum:

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

Bu paketleri kullanıyorum:

 "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",

İndeksler için akıcı API
Michael Freidgeim

Yanıtlar:


329

EF çekirdeğinde veri ek açıklamalarını kullanarak Dizinler oluşturamazsınız, ancak bunu Fluent API kullanarak yapabilirsiniz.

Bunun gibi {Db}Context.cs:

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

... veya buildAction ile aşırı yüklemeyi kullanıyorsanız:

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

Bununla ilgili daha fazla bilgiyi buradan okuyabilirsiniz: Dizinler


1
Yardımınız için çok teşekkür ederim, bu doğru çözüm!
Vadim M

MS Kimlik şemasını kullanırken işe yarayan bir çözüm arayan birinin buraya gelmesi durumunda, E-posta (AspNetUsers varlığının) yerine Normalize E-posta alanına benzersiz kısıtlamayı ayarlamanızı öneririm. Farklı büyük / küçük harf kullanımı, aynı e-posta adresi olsa bile, db'nin harmanlama ayarına bağlı olarak kısıtlamayı ihlal etmeyebilir.
Tom

4
Bu kod string türündeki sütun için çalışmıyor :( Dize sütununa benzersiz kısıtlama eklemenin bir yolu var mı?
Johar Zaman

GitHasAlternateKey
Chamika Sandamal

1
Bunu üzerinde çalışırken denedim ama şimdi uygulamaya ihtiyacım yok. Btw Yorumunuz için teşekkür ederiz. @Sampath
Johar Zaman

83

Ayrıca, birden çok sütunda Benzersiz sınırlamalar oluşturmak istiyorsanız, bunu kolayca yapabilirsiniz (@ Sampath'in bağlantısını izleyerek )

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

10

EF Core için Çözüm

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

DB tablosu şöyle görünecektir:

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

EF Core belgelerine başvuru


11
EF Core belgelerine göre: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.
bigworld12


4

OP, bir Benzersiz Anahtar için bir Varlık sınıfına bir Öznitelik eklemenin mümkün olup olmadığını soruyor. Kısa cevap, mümkün olduğu, ancak EF Core Ekibinden kullanıma hazır bir özellik olmadığıdır. Entity Framework Core varlık sınıflarınıza Benzersiz Anahtarlar eklemek için bir Öznitelik kullanmak isterseniz, burada yayınladığım şeyi yapabilirsiniz.

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

[UniqueKey] özniteliği, Microsoft tarafından tanımlanmış bir özniteliktir? yoksa kendisi mi tanımlamalı?
Muhammed Osman

[UniqueKey] özniteliği, .cs varlık sınıfları içinde (DbContext'in OnModelCreating () yöntemiyle değil) benzersiz anahtarların eklenmesini sağlamak için geliştirdiğim özel bir Özniteliktir
Justin Tubbs

3
Bu harika. Lütfen geliştirdiğiniz özel niteliğin kodunu koyar mısınız ?!
Muhammed Osman


3

Model yapılandırması aracılığıyla EF çekirdeğinde kullanmak için

public class ApplicationCompanyConfiguration : IEntityTypeConfiguration<Company>
{
    public void Configure(EntityTypeBuilder<Company> builder)
    {
        builder.ToTable("Company"); 
        builder.HasIndex(p => p.Name).IsUnique();
    }
}

2

Tüm bu çözümleri deneyen ancak çalışmayan biri için bunu deneyin, benim için çalıştı

protected override void OnModelCreating(ModelBuilder builder)
{

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

}

2

Ef core benzersiz yapılandırmayı destekler.

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

Ef core birden çok benzersiz anahtarı destekler

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Account>()
      .HasKey(account => new { account.Id, account.Email, account.RoleId });
}

Taşıma yapmak ve veritabanını güncellemek için ef core komutunu çalıştırmayı unutmayın

>> dotnet ef migrations add MigrationName -c YourDbContextName
>> dotnet ef database update -c YourDbContextName

1

Bu yöntemlerin hiçbiri benim için .NET Core 2.2'de işe yaramadı, ancak farklı bir birincil anahtar tanımlamak için sahip olduğum bazı kodları bu amaçla çalışacak şekilde uyarlayabildim.

Aşağıdaki örnekte OutletRef alanının benzersiz olduğundan emin olmak istiyorum:

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

Bu, gerekli benzersiz dizini veritabanına ekler. Yine de yapmadığı şey, özel bir hata mesajı belirtme yeteneği sağlamaktır.


0

Akıcı api kullanarak Unique key index ekleyebiliriz. Aşağıdaki kod benim için çalıştı

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.