1. 程式人生 > 實用技巧 >Entity Framework Core - 建立並配置模型-索引 Indexes

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 override
void 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
        });
}