Entity Framework Core - 建立並配置模型-索引 Indexes
索引
索引是跨多個數據儲存區的常見概念。雖然它們在資料儲存中的實現可能有所不同,但它們用於提高基於一列(或一組列)的查詢效率。
不能使用資料註釋建立索引。你可以使用Fluent 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對每個不同的屬性集只支援一個索引。如果您使用Fluent API在一組屬性上配置索引,這些屬性已經定義了索引(按照約定或以前的配置),那麼您將更改該索引的定義。如果您想要進一步配置根據約定建立的索引,這很有用。
1、唯一索引
預設情況下,索引不是唯一的:允許多行索引的列有相同的值。你可以讓一個索引唯一,如下所示:
protected overridevoid OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .IsUnique(); }
試圖為唯一索引的列集插入多個具有相同值的實體將導致丟擲異常。
2、索引名稱
按照約定,在關係資料庫中建立的索引命名為IX_<型別名>_<屬性名>。對於複合索引,<屬性名>將成為一個下劃線分隔的屬性名列表。
你可以使用Fluent API來設定在資料庫中建立的索引的名稱:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .HasDatabaseName("Index_Url"); }
3、索引篩選器
有些關係資料庫允許指定過濾索引或部分索引。這允許您僅為列值的子集建立索引,從而減少索引的大小並提高效能和磁碟空間使用。有關SQL Server過濾索引的更多資訊,請參閱文件。
你可以使用Fluent API在索引上指定一個過濾器,它以SQL表示式的形式提供:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .HasFilter("[Url] IS NOT NULL"); }
當使用SQL Server提供程式時,EF為唯一索引中所有可為空的列添加了一個“IS NOT NULL”過濾器。若要重寫此約定,您可以提供一個空值:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasIndex(b => b.Url) .IsUnique() .HasFilter(null); }
3、包含列
一些關係資料庫允許您配置一組列,這些列包含在索引中,但不是索引“鍵”的一部分。當查詢中的所有列都作為鍵或非鍵列包含在索引中時,這可以顯著提高查詢效能,因為表本身不需要被訪問。有關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 }); }