먼저 코드를 사용하여 Entity Framework 6.2에서 인덱스를 만드는 방법


112

new를 사용하는 대신 코드 우선을 사용하여 속성 / 열에 인덱스를 만드는 방법이 IndexAttribute있습니까?


5
인덱스는 엔티티 모델 개념이 아니라 데이터베이스 개념입니다. 속성을 사용하거나 유창한 API를 통해 색인을 지정할 수 있더라도 실제로는 애플리케이션에서 아무 작업도 수행하지 않습니다. EF가 데이터베이스를 생성 할 때 사용하는 명령 일뿐입니다. 이러한 지침은 데이터베이스 스키마 조작과 관련된 코드 우선 마이그레이션에 속한다고 생각합니다.
JC Ford

답변:


84

잘 26.10.2017 Entity Framework 6.2가 공식적으로 출시되었습니다 . 그것은 포함 가능성 유창함 API를 통해 쉽게 인덱스를 정의 할 수 있습니다. 사용하는 것은 이미 6.2의 베타에서 발표 되었습니다.

이제 HasIndex()방법을 사용할 IsUnique()수 있으며 고유 인덱스 여야 하는 경우 뒤에 올 수 있습니다 .

간단한 비교 (전 / 후) 예 :

// before 
modelBuilder.Entity<Person>()
        .Property(e => e.Name)
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(new IndexAttribute { IsUnique = true }));

// after
modelBuilder.Entity<Person>()
    .HasIndex(p => p.Name)
    .IsUnique();

// multi column index
modelBuilder.Entity<Person>()
    .HasIndex(p => new { p.Name, p.Firstname })
    .IsUnique();

인덱스를로 클러스터 된 것으로 표시 할 수도 있습니다 .IsClustered().


# 1 수정

다중 열 인덱스에 대한 예제와 인덱스를 클러스터형으로 표시하는 방법에 대한 추가 정보를 추가했습니다.


# 2 수정

추가 정보로 EF Core 2.1에서는 현재 EF 6.2와 완전히 동일합니다.
다음 은 MS Doc 기사입니다.


이것은 대단합니다! 다중 열 인덱스가있는 경우 다음과 같은 것으로 가정합니다. .HasIndex (p => new {p.Name, p.Xyz})
Valo

아, 죄송합니다. 이어야합니다 new. 내가 고칠 게.
ChW 2011

Core 2.x에서 동일한 코드를 작성하는 방법을 보여 주시겠습니까?
user3417479

내가 아는 한 "이후"및 "다중 열 인덱스"에 표시된 것과 동일한 코드 여야합니다.
ChW

87

현재 유창한 API를 통해 색인을 생성하기위한 "일급 지원" 은 없지만 유창한 API를 통해 속성을 Annotation API의 속성이있는 것으로 표시 할 수 있습니다. 이렇게하면 Index유창한 인터페이스를 통해 속성 을 추가 할 수 있습니다 .

다음은 EF에 대한 문제 사이트의 작업 항목에 대한 몇 가지 예입니다.

단일 열에 인덱스를 만듭니다.

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new IndexAttribute()));

단일 열에 여러 인덱스 :

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new[]
            {
                new IndexAttribute("Index1"),
                new IndexAttribute("Index2") { IsUnique = true }
            }));

다중 열 인덱스 :

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty1)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new IndexAttribute("MyIndex", 1)));

modelBuilder.Entity<MyEntity>()
    .Property(e => e.MyProperty2)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName, 
        new IndexAnnotation(new IndexAttribute("MyIndex", 2)));

위의 기술을 사용하면 다음 마이그레이션을 스캐 폴드 할 때 함수 .CreateIndex()에서 호출이 자동으로 생성됩니다 Up()(또는 마이그레이션을 사용하지 않는 경우 데이터베이스에서 자동으로 생성됨).


4
열에 인덱스를 추가 할 수 있지만 기본 키에 생성 된 클러스터형 인덱스를 제거하지 않습니다. hasKey는 기본적으로 제거되지 않는 기본 키에 클러스터형 인덱스를 생성합니다. .Primarykey(x=>x.id,clustered:false)방법에 clusered : false를 지정하여 생성 된 마이그레이션 파일에서 명시 적으로 제거해야합니다
Joy

8
나는 HasAnnotation방법을 시도했지만 이와 같은 방법이 없습니다. 하지만 나는 HasColumnAnnotation당신이 제공하는 매개 변수를 받아들이는 이름 을 가진 방법을 찾았습니다 . 답변을 업데이트해야합니까, 아니면 제가 틀렸습니까?
Hakan Fıstık

@HakamFostok 저는 EF 사이트에서 직접 예제를 가져 왔습니다. 버전 중 하나에서 이름이 변경되었거나 원래 버전에 오타가있을 수 있습니다.
스콧의 전관

3
올해 초 디자인 회의에서 다음 링크의 맨 아래를 참조하십시오. "HasAnnotation을 HasColumnAnnotation으로 이름 바꾸기 (코드베이스의 다른 관련 위치 포함)". entityframework.codeplex.com/…
Zac Charles

36

이 작업을 훨씬 쉽게하기 위해 몇 가지 확장 메서드를 만들고 nuget 패키지로 래핑했습니다.

EntityFramework.IndexingExtensions너겟 패키지를 설치하십시오 .

그런 다음 다음을 수행 할 수 있습니다.

public class MyDataContext : DbContext
{
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Customer>()
        .HasIndex("IX_Customers_Name",          // Provide the index name.
            e => e.Property(x => x.LastName),   // Specify at least one column.
            e => e.Property(x => x.FirstName))  // Multiple columns as desired.

        .HasIndex("IX_Customers_EmailAddress",  // Supports fluent chaining for more indexes.
            IndexOptions.Unique,                // Supports flags for unique and clustered.
            e => e.Property(x => x.EmailAddress)); 
  }
}

프로젝트 및 소스 코드는 여기에 있습니다 . 즐겨!


나는 패키지를 정말 좋아하지만 up 스크립트에서 스캐 폴딩 후 인덱스 이름이 때때로 누락되는 것 같습니다. 내 색인에서 4 개 이상의 속성을 사용할 때만 나타납니다. EF 6.1.3을 사용하고 있습니다.
Mixxiphoid

@Mixxiphoid- 여기 에 지원 세부 정보와 함께 문제를 기록해 주 시겠습니까? 또한 1.0.0에 버그 가 있었으므로 버전 1.0.1이 있는지 확인하십시오 .
Matt Johnson-Pint 2015

버전 1.0.1이 있습니다. 문제를 기록 할 것이지만 지금은 기록 할 수 없습니다.
Mixxiphoid

인덱스 참여 열 순서를 내림차순에 추가하려면 어떻게합니까? 기본 .HasIndex ( "IX_Customers_EmailAddress", IndexOptions.Unique으로 ... 인덱스에 참여하는 모든 열의 오름차순을 작성합니다.
GDroid

@GDroid-불행히도 이것은 EF의 IndexAttribute클래스에 의해 노출 되지 않으므로 내 라이브러리에 포함 할 수 없습니다.
Matt Johnson-Pint

24

명시적인 이름없이 :

[Index]
public int Rating { get; set; } 

특정 이름으로 :

[Index("PostRatingIndex")] 
public int Rating { get; set; }

인덱스는
폐기 된

1
@HamedZakeryMiab 어떤 버전의 Entity Framework를 사용하고 있습니까? 인덱스는 더 이상 사용되지 않습니다.
Hugo Hilário 2016

실례합니다 EntityFramework. 포함하는 것을 잊었습니다 . 그 어셈블리에 포함되어 있습니다. NS에 대해 혼란스러워했습니다.
Hamed Zakery Miab 2016

@HamedZakeryMiab 맞아, 정말 혼란 스러웠 어! System.DataAnnotations의 일부라고 생각했습니다! 확실히 엔터티 프레임 워크 패키지입니다
AlbatrossCafe

3
질문에 다음 진술 instead of using the new IndexAttribute이 포함되어 있습니다 .
Hakan Fıstık

22

EF 6.1부터 특성 [Index]이 지원됩니다. 고유 색인에
사용 [Index(IsUnique = true)]합니다.
다음은 Microsoft링크입니다.

public class User 
{ 
    public int UserId { get; set; } 

    [Index(IsUnique = true)] 
    [StringLength(200)] 
    public string Username { get; set; } 

    public string DisplayName { get; set; } 
}

2
이 이론적으로 질문에 대답 할 수 있습니다 동안, 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
Enamul Hassan 2016 년

@manetsus 아주 좋아요. 변경 사항을 반영하기 위해 코드 조각을 추가했습니다.
Darie Dorlus 2016 년

3
문자열 길이가 필요합니다. 그렇지 않으면 '인덱스에서 키 열로 사용하기에 잘못된 유형입니다'예외가 표시됩니다. 내 동료는 Conntext에서 modelBuilder 솔루션을 선호하므로 User 클래스를 복잡하게 만들지 않는 것이 좋습니다.
앤드류 머리

고유성을 위해 여러 열이있는 인덱스는 어떻습니까? 여러 열로 된 고유 키 인덱스를 갖는 것이 매우 일반적입니다 ...
enorl76

1
@ enorl76 이것도 지원됩니다. 각 열에 대해 다음과 같은 속성을 사용해야합니다. Microsoft[Index("IX_BlogIdAndRating", 2)] public int Rating { get; set; } [Index("IX_BlogIdAndRating", 1)] public int BlogId { get; set; } 의 참조
Darie Dorlus

8

Entity Framework 6

Property(c => c.MyColumn)
        .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_MyIndex")));

다음을 사용하여 추가하십시오.

using System.Data.Entity.Infrastructure.Annotations;
using System.ComponentModel.DataAnnotations.Schema;

7

INDEX 데이터 주석 코드 첫 번째 데이터 주석을 사용할 수 있습니다.


3
최대 키 길이는 nvarchar의 경우 900 바이트이고 varchar의 경우 450 바이트입니다. 코드를 먼저 사용하는 경우 문자열 속성은 nvarchar가되며 [[StringLength (450)]에서와 같이 "StringLength"속성을 포함해야합니다.
dunwan

EF 6.1에서는 이것이 정답입니다. docs.microsoft.com/en-us/ef/ef6/modeling/code-first/…
Chris Schaller

2

POCO의 속성을 사용하지 않으려면 항상 다음과 같이 할 수 있습니다.

context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ..."); 

사용자 지정 DbInitializer파생 클래스 에서이 문을 실행할 수 있습니다 . 그래도 Fluent API 방법을 알지 못합니다.


1
물론 이죠, Mert. 현재 마이그레이션을 사용하고 있으며 Up () 메서드에 CreateIndex ( "dbo.Table1", "Column1", true, "Column1_IX") 및 Down () DropIndex (( "dbo.Table1)를 넣을 수도 있습니다. . ","Column1_IX ") 난 그냥 ... 그들도 유창하게 API를 추가 한 기대했다
발로

1

추가 코드를 피하기 위해 유창한 EF에서 사용할 확장 메서드를 작성합니다.

public static PrimitivePropertyConfiguration HasIndexAnnotation(
    this PrimitivePropertyConfiguration primitivePropertyConfiguration, 
    IndexAttribute indexAttribute = null
    )
{
    indexAttribute = indexAttribute ?? new IndexAttribute();

    return primitivePropertyConfiguration
        .HasColumnAnnotation(
            IndexAnnotation.AnnotationName, 
            new IndexAnnotation(indexAttribute)
        );
}

다음과 같이 사용하십시오.

Property(t => t.CardNo)
    .HasIndexAnnotation();

또는 색인에 일부 구성이 필요한 경우 다음과 같이하십시오.

Property(t => t.CardNo)
    .HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });

1

이 중 하나를 사용할 수 있습니다

// 인덱스

 this.HasIndex(e => e.IsActive)
            .HasName("IX_IsActive");

또는

  this.Property(e => e.IsActive).HasColumnAnnotation(
            "Index",
            new IndexAnnotation(new IndexAttribute("IX_IsActive")));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.