新しい IndexAttribute
を使用する代わりに、コードファーストを使用してプロパティ/列にインデックスを作成する方法はありますか?
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アーティクルです。
現在、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()
呼び出しが自動的に作成されます(または、移行を使用していない場合はデータベースで自動的に作成されます)。
これを簡単にするために、いくつかの拡張メソッドを作成し、それらを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));
}
}
プロジェクトとソースコードはこちら 。楽しい!
明示的な名前なし:
[Index]
public int Rating { get; set; }
特定の名前:
[Index("PostRatingIndex")]
public int Rating { get; set; }
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; }
}
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;
INDEXデータアノテーションを使用できます Code First Data Annotations
POCOで属性を使用したくない場合は、次のようにいつでも実行できます。
context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");
このステートメントは、カスタムDbInitializer
派生クラスで実行できます。しかし、これを行うFluent APIの方法は知りません。
これのいずれかを使用できます
//インデックス
this.HasIndex(e => e.IsActive)
.HasName("IX_IsActive");
または
this.Property(e => e.IsActive).HasColumnAnnotation(
"Index",
new IndexAnnotation(new IndexAttribute("IX_IsActive")));
余分なコードを回避するために、流れるような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 });