EFCore基礎教程


查詢數據

  Entity Framework Core 使用語言集成查詢 (LINQ) 來查詢數據庫中的數據。 通過 LINQ 可使用 C#(或你選擇的其他 .NET 語言)基於派生上下文和實體類編寫強類型查詢。 LINQ 查詢的一種表示形式會傳遞給數據庫提供程序,進而轉換為特定於數據庫的查詢語言(例如,適用於關系數據庫的 SQL)。

查詢的生命周期

下面是每個查詢所經歷的過程的高級概述。

  1. LINQ 查詢由 Entity Framework Core 處理,用於生成已准備好由數據庫提供程序處理的表示形式
    1. 結果會被緩存,以便每次執行查詢時無需重復進行此處理
  2. 結果會傳遞到數據庫提供程序
    1. 數據庫提供程序會識別出查詢的哪些部分可以在數據庫中求值
    2. 查詢的這些部分會轉換為特定數據庫的查詢語言(例如,關系數據庫的 SQL)
    3. 一個或多個查詢會發送到數據庫並返回結果集(返回的是數據庫中的值,而不是實體實例中的)
  3. 對於結果集中的每一項
    1. 如果這是跟蹤查詢,EF 會檢查數據是否表示上下文實例內更改跟蹤器中的現有實體
      • 如果是,則會返回現有實體
      • 如果不是,則會創建新實體、設置更改跟蹤並返回該新實體
    2. 如果這是非跟蹤查詢,EF 會檢查數據是否表示此查詢結果集中的現有實體
      • 如果是,則會返回現有實體 (1)
      • 如果不是,則會創建新實體並返回該新實體

(1) 非跟蹤查詢使用弱引用跟蹤已返回的實體。 如果具有相同標識的上一個結果超出范圍,並遇到垃圾回收機制執行,則可能會獲得新的實體實例。

跟蹤與非跟蹤查詢

跟蹤查詢

跟蹤行為可控制 Entity Framework Core 是否將有關實體實例的信息保留在其更改跟蹤器中。 如果已跟蹤某個實體,則該實體中檢測到的任何更改都會在 SaveChanges() 期間永久保存到數據庫。 Entity Framework Core 還會修正從跟蹤查詢中獲取的實體與先前已加載到 DbContext 實例中的實體兩者之間的導航屬性。

默認情況下,跟蹤返回實體類型的查詢。 這表示可以更改這些實體實例,然后通過 SaveChanges() 持久化這些更改。

在以下示例中,將檢測到對博客評分所做的更改,並在 SaveChanges() 期間將這些更改持久化到數據庫中。

using (var context = new BloggingContext())
{
    var blog = context.Blogs.SingleOrDefault(b => b.BlogId == 1);
    blog.Rating = 5;
    context.SaveChanges();
}

 

非跟蹤查詢

在只讀方案中使用結果時,非跟蹤查詢十分有用。 可以更快速地執行非跟蹤查詢,因為無需設置更改跟蹤信息。

可以交換單個非跟蹤查詢:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .AsNoTracking()
        .ToList();
}

 

還可以在上下文實例級別更改默認跟蹤行為:

using (var context = new BloggingContext())
{
    context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

    var blogs = context.Blogs.ToList();
}

跟蹤和投影

即使查詢的結果類型不是實體類型,但如果結果包含實體類型,則默認情況下也會跟蹤這些實體類型。 在以下返回匿名類型的查詢中,會跟蹤結果集中 Blog 的實例。

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Select(b =>
            new
            {
                Blog = b,
                Posts = b.Posts.Count()
            });
}

 

如果結果集不包含任何實體類型,則不會執行跟蹤。 在以下返回匿名類型(具有實體中的某些值,但沒有實際實體類型的實例)的查詢中,不會執行跟蹤。

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Select(b =>
            new
            {
                Id = b.BlogId,
                Url = b.Url
            });
}

 

執行查詢時

調用 LINQ 運算符時,只會構建查詢在內存中的表示形式。 只有在使用結果時,查詢才會發送到數據庫。

導致查詢發送到數據庫的最常見操作如下:

  • 在 for 循環中循環訪問結果
  • 使用 ToListToArraySingleCount 等操作
  • 將查詢結果數據綁定到 UI


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM