索引是跨多個數據存儲區的常見概念。 盡管它們在數據存儲中的實現可能會有所不同,但也可用於基於列(或一組列)更高效地進行查找。
不能使用數據批注創建索引。 您可以使用 "熟知 API" 按如下方式為單個列指定索引:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url); }
您還可以為多個列指定索引:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Person>() .HasIndex(p => new { p.FirstName, p.LastName }); }
備注
按照約定,將在用作外鍵的每個屬性(或一組屬性)中創建索引。
EF Core 每個不同的屬性集僅支持一個索引。 如果使用 "熟知 API" 來配置已定義索引的屬性集的索引(按照約定或以前的配置),則會更改該索引的定義。 如果要進一步配置由約定創建的索引,則此操作非常有用。
索引唯一性
默認情況下,索引不唯一:允許多行具有與索引的列集相同的值。 可以使索引唯一,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .IsUnique(); }
嘗試為索引的列集插入多個具有相同值的實體將導致引發異常。
索引名稱
按照約定,在關系數據庫中創建的索引將命名為 IX_<type name>_<property name>
。 對於復合索引,<property name>
變成以下划線分隔的屬性名稱列表。
您可以使用 "熟知 API" 設置在數據庫中創建的索引的名稱:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .HasName("Index_Url"); }
索引篩選器
某些關系數據庫允許您指定篩選索引或部分索引。 這使您可以只為列的值的一個子集編制索引,從而減少索引的大小並改善性能和磁盤空間的使用情況。 有關 SQL Server 篩選索引的詳細信息,請參閱文檔。
您可以使用熟知的 API 來指定索引的篩選器,作為 SQL 表達式提供:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .HasFilter("[Url] IS NOT NULL"); }
當使用 SQL Server 提供程序 EF 時,將為唯一索引中包含的所有可以為 null 的列添加 'IS NOT NULL'
篩選器。 若要重寫此約定,可以提供 null
值。
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .IsUnique() .HasFilter(null); }
包含列
某些關系數據庫允許配置一組列,這些列包含在索引中,但不是其 "鍵" 的一部分。 當查詢中的所有列都作為鍵列或非鍵列包含在索引中時,這可以顯著提高查詢性能,因為表本身無需訪問。 有關 SQL Server 包含列的詳細信息,請參閱文檔。
在下面的示例中,Url
列是索引鍵的一部分,因此對該列的任何查詢篩選都可以使用索引。 但此外,僅訪問 Title
和 PublishedOn
列的查詢將不需要訪問表,並且將更有效地運行:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>() .HasIndex(p => p.Url) .IncludeProperties(p => new { p.Title, p.PublishedOn }); }