Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core 7
Для увеличения производительности поиска в базе данных применяются индексы. По умолчанию индекс создается для каждого свойства, которое используется в качестве внешнего ключа. Но с помощью 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 и для него установлена уникальность.