web-dev-qa-db-ja.com

Entity FrameworkCoreを使用してクラスター化インデックスを作成する方法

EF6.1から、プロパティにクラスター化インデックスを指定する方法があります

public class Person 
{
  [Index(IsClustered = true, IsUnique = true)]
  public long UserName { get; set; }
}

しかし、このインデックス属性は現在EFコアに含まれていないようです。 EF Coreでは、これをどのように達成しますか?

11
Ray

現在のEFCoreドキュメントから- Indexes section:

データ注釈

データ注釈を使用してインデックスを作成することはできません。

ただし、Fluent APIを介して指定することはできます(SQLServer固有の機能を示しているように見えるForSqlServerプレフィックスを持つ拡張メソッドに注意してください)。

modelBuilder.Entity<Person>()
    .HasIndex(e => e.UserName)
    .IsUnique()
    .ForSqlServerIsClustered();
20
Ivan Stoev

組み込みのサポートがない場合は、独自のカスタム属性を使用してモデルプロパティに注釈を付け、OnModelCreating()に適用できます。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    foreach (var entity in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var prop in entity.GetProperties())
        {
            var attr = prop.PropertyInfo.GetCustomAttribute<IndexAttribute>();
            if (attr != null)
            {
                var index = entity.AddIndex(prop);
                index.IsUnique = attr.IsUnique;
                index.SqlServer().IsClustered = attr.IsClustered;
            }
        }
    }
}

単純なマーカー属性クラスの場合:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class IndexAttribute : Attribute
{
    public bool IsUnique { get; set; } 
    public bool IsClustered { get; set; } 
}

次に、モデルクラスで、属性を追加してセカンダリインデックスを作成します。

public class User
{
    public int UserId { get; set; }
    [Index(IsUnique = true, IsClustered = true)]
    public string Nickname { get; set; }
}
5
StephenD

EF Core3.0以降の場合IsClusteredを使用できるようになりました。

modelBuilder.Entity<Person>()
.HasIndex(e => e.UserName)
.IsUnique()
.IsClustered();

.ForSqlServerIsClustered()は廃止としてマークされるようになりました。

また、テーブルに主キーがある場合は、ユーザー名にクラスタリングを追加する前に、そのクラスターを明示的に削除する必要がある場合もあることに注意してください。

modelBuilder.Entity<Person>()
.HasKey(e => e.PersonId)
.IsClustered(false);

modelBuilder.Entity<Person>()
.HasIndex(e => e.UserName)
.IsUnique()
.IsClustered();
3
sarin

または、これも機能します。たとえば、年齢別にクラスター化する場合は...

            modelBuilder
            .Entity<Person>()
            .Property(t => t.Age)
            .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsClustered = true}));
0
andrew pate