無索引鍵實體類型
注意
這項功能已新增在查詢類型的名稱下。 稍後會重新命名為無索引鍵實體類型。
除了一般實體類型之外,EF Core 模型還可以包含 無索引鍵實體類型 ,可用來對不包含索引鍵值的資料執行資料庫查詢。
定義無索引鍵實體類型
無索引鍵實體類型可以定義如下:
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
無索引鍵實體類型特性
無索引鍵實體類型支援許多與一般實體類型相同的對應功能,例如繼承對應和導覽屬性。 在關聯式存放區上,他們可以透過 Fluent API 方法或資料批註來設定目標資料庫物件和資料行。
不過,它們與一般實體類型不同,因為它們:
- 無法定義索引鍵。
- 永遠不會追蹤 DbCoNtext 中的 變更,因此永遠不會在資料庫上插入、更新或刪除。
- 絕不會依慣例探索。
- 僅支援流覽對應功能的子集,特別是:
- 他們可能永遠不會充當關係的主要結尾。
- 他們可能沒有擁有實體的導覽
- 它們只能包含指向一般實體的參考導覽屬性。
- 實體不能包含無索引鍵實體類型的導覽屬性。
- 必須使用
[Keyless]
資料批註或方法呼叫來.HasNoKey()
設定。 - 可能對應至 定義查詢 。 定義查詢是在模型中宣告的查詢,做為無索引鍵實體類型的資料來源。
- 可以有階層,但必須對應為 TPH。
- 無法使用資料表分割或實體分割。
使用方式情節
無索引鍵實體類型的一些主要使用案例如下:
- 做為 SQL 查詢 的 傳回型別。
- 對應至不包含主鍵的資料庫檢視。
- 對應至未定義主鍵的資料表。
- 對應至模型中定義的查詢。
對應至資料庫物件
使用 ToTable
或 ToView
Fluent API,將無索引鍵實體類型對應至資料庫物件。 從 EF Core 的觀點來看,此方法中指定的資料庫物件是檢 視 ,這表示它會被視為唯讀查詢來源,而且不能是更新、插入或刪除作業的目標。 不過,這並不表示資料庫物件實際上是資料庫檢視的必要專案。 它也可以是將視為唯讀的資料庫資料表。 相反地,針對一般實體類型,EF Core 會假設方法中指定的 ToTable
資料庫物件可以視為 資料表 ,這表示它可以當做查詢來源使用,但也以更新、刪除和插入作業為目標。 事實上,您可以在 中 ToTable
指定資料庫檢視的名稱,只要檢視設定為可在資料庫上更新,所有專案都應該正常運作。
範例
下列範例示範如何使用無索引鍵實體類型來查詢資料庫檢視。
提示
您可以檢視本文中的 GitHut 範例。
首先,我們會定義簡單的部落格和文章模型:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
}
接下來,我們會定義簡單的資料庫檢視,以讓我們查詢與每個部落格相關聯的文章數目:
db.Database.ExecuteSqlRaw(
@"CREATE VIEW View_BlogPostCounts AS
SELECT b.Name, Count(p.PostId) as PostCount
FROM Blogs b
JOIN Posts p on p.BlogId = b.BlogId
GROUP BY b.Name");
接下來,我們會定義類別來保存資料庫檢視的結果:
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
接下來,我們會使用 HasNoKey
API 在 OnModelCreating 中 設定無索引鍵實體類型。
我們使用 Fluent 組態 API 來設定無索引鍵實體類型的對應:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<BlogPostsCount>(
eb =>
{
eb.HasNoKey();
eb.ToView("View_BlogPostCounts");
eb.Property(v => v.BlogName).HasColumnName("Name");
});
}
接下來,我們會將 設定 DbContext
為 包含 DbSet<T>
:
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }
最後,我們可以以標準方式查詢資料庫檢視:
var postCounts = db.BlogPostCounts.ToList();
foreach (var postCount in postCounts)
{
Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
Console.WriteLine();
}
提示
請注意,我們也定義了內容層級查詢屬性 (DbSet),以作為針對此類型之查詢的根目錄。
提示
若要使用記憶體內部提供者測試對應至檢視的無索引鍵實體類型,請透過 ToInMemoryQuery 將其對應至查詢。 如需詳細資訊,請參閱記憶體內部提供者檔 。