Подтвердить что ты не робот

Как создать индекс в Entity Framework 6.2 с первым кодом

Есть ли способ создать индекс для свойства/столбца с использованием кода сначала, вместо использования IndexAttribute?

4b9b3361

Ответ 1

Хорошо 26.10.2017 Entity Framework 6.2 был официально выпущен. Он включает в себя возможность легко определять индексы с помощью Fluent 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 сейчас.
Вот MSc Doc artcile в качестве ссылки.

Ответ 2

В настоящее время нет "поддержка первого класса" для создания индекса через свободный API, но то, что вы можете сделать, - это свободный API вы можете пометить свойства как имеющие атрибуты из 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(), если вы поднимете следующую миграцию (или будете автоматически созданы в базе данных, если вы не используете миграции).

Ответ 3

Я создал некоторые методы расширения и завернул их в пакет 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)); 
  }
}

Проект и исходный код здесь. Наслаждайтесь!

Ответ 4

Без явного имени:

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

С конкретным именем:

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

Ответ 5

Начиная с 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; } 
}

Ответ 6

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

Если вы не хотите использовать атрибуты в POCO, вы всегда можете сделать это следующим образом:

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

Вы можете выполнить этот оператор в своем обычном DbInitializer производном классе. Я не знаю, как это сделать Fluent API.

Ответ 9

Я пишу метод расширения для использования в свободном 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 });

Ответ 10

Вы можете использовать один из этого

//Индексы

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

или же

  this.Property(e => e.IsActive).HasColumnAnnotation(
            "Index",
            new IndexAnnotation(new IndexAttribute("IX_IsActive")));