Настройка индексов

Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core 7

Последнее обновление: 16.11.2020

Для увеличения производительности поиска в базе данных применяются индексы. По умолчанию индекс создается для каждого свойства, которое используется в качестве внешнего ключа. Но с помощью Fluent API мы можем переопределить это поведение. Для установки индекса применяется метод HasIndex():

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; }
	public ApplicationContext()
	{
		Database.EnsureDeleted();
		Database.EnsureCreated();
	}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=efbasicsappdb;Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasIndex(u => u.Passport);
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Passport { get; set; }
    public string PhoneNumber { get; set; }
}

Уникальность индексов

С помощью дополнительного метода IsUnique() можно указать, что индекс должен иметь уникальное значение. Тем самым мы гарантируем, что в базе данных может быть только один объект с определенным значением для свойства-индекса:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().HasIndex(u => u.Passport).IsUnique();
}

Составные индексы

Также можно определить индексы сразу для нескольких свойств:

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; }
	public ApplicationContext()
	{
		Database.EnsureDeleted();
		Database.EnsureCreated();
	}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\\mssqllocaldb;Database=efbasicsappdb;Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasIndex(u => new { u.Passport, u.PhoneNumber });
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Passport { get; set; }
    public string PhoneNumber { get; set; }
}

Имя индекса

Для установки имени индекса применяется метод HasDatabaseName(), в который передается имя индекса:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.Entity<User>()
		.HasIndex(u => u.PhoneNumber)
		.HasDatabaseName("PhoneIndex");
}

В данном случае для индекса будет использоваться столбец PhoneNumber, а называться он будет "PhoneIndex".

Фильтры индексов

Некоторые системы управления базами данных позволяют определять индексы с фильрами или частичные индексы, которые позволяют выполнять индексацию только по ограниченному набору значений, что увеличивает производительность и уменьшает использование дискового простанства. И EntityFramework Core также позволяет создавать подобные индексы. Для этого применяется метод HasFilter(), в который передается sql-выражение, которое определяет условие фильтра. Например:

using Microsoft.EntityFrameworkCore;

namespace HelloApp
{
    public class ApplicationContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public ApplicationContext()
        {
            Database.EnsureDeleted();
            Database.EnsureCreated();
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=efbasicsappdb;Trusted_Connection=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>()
                .HasIndex(u => u.PhoneNumber)
                .HasFilter("[PhoneNumber] IS NOT NULL"); ;
        }
    }

    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Passport { get; set; }
        public string PhoneNumber { get; set; }
    }
}

В данном случае в качестве индекса будет использоваться столбец PhoneNumber. Причем только для тех строк, у которых в столбце PhoneNumber значение не равно NULL.

Настройка индексов с помощью атрибутов

Начиная с версии EntityFramework Core 5.0 во фреймворк был добавлен атрибут IndexAttribute, который позволяет через атрибут настроить индекс. Например:

[Index("PhoneNumber")]
public class User
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Passport { get; set; }
	public string PhoneNumber { get; set; }
}

Первый и обязательный параметр атрибута указывает на свойство, с которым будет ассоциирован индекс. В данном случае это свойство PhoneNumber. Но также он может принимать набор свойств, для которых создается индекс. В этом случае названия свойств просто перечисляются через запятую:

[Index("PhoneNumber", "Passport")]
public class User
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Passport { get; set; }
	public string PhoneNumber { get; set; }
}

С помощью дополнительных параметров можно настроить уникальность и имя индекса:

[Index("PhoneNumber", IsUnique =true, Name ="Phone_Index")]
public class User
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Passport { get; set; }
	public string PhoneNumber { get; set; }
}

В данном случае индекс будет называться Phone_Index и для него установлена уникальность.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850