Entity Framework Core는 고유 제약 조건 코드 우선 추가


152

속성을 사용하여 필드에 고유 제약 조건을 추가하는 방법을 찾을 수 없습니다.

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

이 패키지를 사용하고 있습니다 :

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

답변:


301

EF core에서는 데이터 주석을 사용하여 인덱스를 만들 수 없지만 Fluent API를 사용하여 인덱스를 만들 수 있습니다.

내 안에 이렇게 {Db}Context.cs:

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

... 또는 buildAction과 함께 과부하를 사용하는 경우 :

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

당신은 여기에 대한 자세한 내용을보실 수 있습니다 : 인덱스


1
도움을 주셔서 대단히 감사합니다. 올바른 솔루션입니다!
Vadim M

누군가가 MS Identity 스키마를 사용할 때 작동하는 솔루션을 찾고있는 경우 이메일 (AspNetUsers 엔티티)의 NormalizedEmail 필드에 고유 제한 조건을 설정하는 것이 좋습니다. db의 데이터 정렬 설정에 따라 동일한 이메일 주소 인 경우에도 다른 경우를 사용하여 제한 조건을 위반하지 못할 수 있습니다.
Tom

4
이 코드는 문자열 유형의 열에 대해 작동하지 않습니다. (문자열 열에 고유 제한 조건을 추가하는 방법이 있습니까?
Johar Zaman

이동HasAlternateKey
Chamika Sandamal

1
내가이 작업을 할 때 이것을 시도했지만 지금은 이것을 구현할 필요가 없습니다. Btw 귀하의 의견에 감사드립니다. @Sampath
Johar Zaman

70

또한 여러 열에 고유 제약 조건을 만들려면 간단하게 수행 할 수 있습니다 (@ Sampath의 링크 ).

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

9

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

DB 테이블은 다음과 같습니다.

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 핵심 문서 참조


11
EF 핵심 문서에 따르면 :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


3

OP는 고유 키의 Entity 클래스에 속성을 추가 할 수 있는지 묻고 있습니다. 짧은 대답은 가능하지만 EF 핵심 팀의 기본 기능은 아닙니다. 속성을 사용하여 Entity Framework Core 엔터티 클래스에 고유 키를 추가하려는 경우 여기에 게시 한 작업을 수행 할 수 있습니다

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] 특성은 Microsoft에서 정의한 특성입니까? 아니면 스스로 정의해야합니까?
모하메드 오스만

[UniqueKey] 속성은 .cs 엔터티 클래스 내에 DbContext의 OnModelCreating () 메서드를 통하지 않고 고유 키를 추가 할 수 있도록 개발 한 사용자 지정 속성입니다.
Justin Tubbs

3
훌륭합니다. 개발 한 사용자 정의 속성의 코드를 입력 해 주시겠습니까?!
Mohammed Osman


2

이 모든 솔루션을 시도했지만 작동하지 않는 사람은이 솔루션을 사용했습니다.

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 코어에서 사용하려면

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

1

이러한 방법 중 어느 것도 .NET Core 2.2에서 작동하지 않았지만이 목적을 위해 작동하기 위해 다른 기본 키를 정의하는 데 필요한 일부 코드를 조정할 수 없었습니다.

아래 예에서 OutletRef 필드가 고유한지 확인하고 싶습니다.

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

데이터베이스에 필요한 고유 인덱스가 추가됩니다. 그러나 수행하지 않는 것은 사용자 정의 오류 메시지를 지정하는 기능을 제공하는 것입니다.


0

유창한 API를 사용하여 고유 키 인덱스를 추가 할 수 있습니다. 아래 코드는 나를 위해 일했습니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.