web-dev-qa-db-ja.com

Entity Framework 6.2で最初にコードを使用してインデックスを作成する方法

新しい IndexAttribute を使用する代わりに、コードファーストを使用してプロパティ/列にインデックスを作成する方法はありますか?

100
Valo

2017年10月26日、Entity Framework 6.2は 正式リリース でした。 Fluent APIを介して簡単にインデックスを定義するための possibility が含まれています。使用するのは、すでに 発表済み 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アーティクルです。

68
ChW

現在、Fluent APIを介してインデックスを作成するための "first class support" はありませんが、Fluent APIを介して、プロパティを注釈APIの属性としてマークできます。これにより、Fluentインターフェイスを介して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()呼び出しが自動的に作成されます(または、移行を使用していない場合はデータベースで自動的に作成されます)。

84

これを簡単にするために、いくつかの拡張メソッドを作成し、それらをnugetパッケージにラップしました。

EntityFramework.IndexingExtensions nugetパッケージをインストールします。

その後、次のことができます。

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

プロジェクトとソースコードはこちら 。楽しい!

36

明示的な名前なし:

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

特定の名前:

[Index("PostRatingIndex")] 
public int Rating { get; set; }
19
Hugo Hilário

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; } 
}
15
Darie Dorlus

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

INDEXデータアノテーションを使用できます Code First Data Annotations

6
Emre

POCOで属性を使用したくない場合は、次のようにいつでも実行できます。

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

このステートメントは、カスタムDbInitializer派生クラスで実行できます。しかし、これを行うFluent APIの方法は知りません。

2
Mert Akcakaya

これのいずれかを使用できます

//インデックス

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

または

  this.Property(e => e.IsActive).HasColumnAnnotation(
            "Index",
            new IndexAnnotation(new IndexAttribute("IX_IsActive")));
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
Omid-RH