[英]Better understanding of Entity Framework Core querying and DbSet impact
我是 Entity Framework 的新手,想對某些事情進行一些澄清。 我了解DbContext
,例如指向帶有連接字符串的 SQL 數據庫。 在DbContext
中,您聲明您希望/計划從所述 SQL 數據庫公開和獲取數據的DbSet<perEachTable>
。
現在,您進入 LINQ,我了解了一些鏈接,例如可枚舉的事物列表和尋找某些符合條件的 where 條件條目。
現在,我更大的問題以及 EF 如何查詢。 您有一個指向 SQL Server 的DbContext
。 它有一張有 25 萬客戶的桌子。 它的主鍵定義為預期的Id
(或CustomerId
)。 您想根據用戶的電子郵件地址查詢和查找客戶(預期查詢的常見類型)。 客戶表在電子郵件上有一個索引。
在我看到的 LINQ 查詢中,它指的是任何表的DbSet
並運行 where 子句,例如
using (var context = new DBCustomers())
{
var query = context.Customer
.Where(c => c.EMail == "someEMail@whereEver.com")
.FirstOrDefault<Customer>();
}
我的想法是整個客戶列表都被從它的 DbSet 上下文中拉下來了。 然后它運行鏈接WHERE
子句來查找電子郵件。 我不認為我想每次都減少 250k 客戶只是為了 LINQ 迭代他們。
為什么WHERE
實際上並沒有使用整個客戶數據集(尤其是當它繼續增長時),只是根據可用的索引進行優化,實際上並沒有把所有東西都拉下來。
這是否只是一個正在應用的魔法黑盒,EF 只是將符合條件的最終條目交給您(或者如果其他更開放的查詢則很少)。
我還看到了使用完全編寫的 SQL 語句和參數化的 EF Core 實例,這是我更習慣做的事情。 讓 SQL Server 引擎根據與合格索引最匹配的顯式條件返回數據。
感謝對基礎操作的澄清。
我不是 EF 方面的專家,但不要求整張桌子。
它不返回IEnumerable
而是返回IQueryable
,它將基於 linq 語句生成 SQL 查詢,並在迭代時在 sql-server 上執行它(例如 foreach 循環)。
您可以使用以下方法獲取 SQL 查詢:
var query = context.Customer.Where(x => x.Id == 1);
Console.WriteLine(query.ToQueryString());
您的代碼DbSet<T>.Where()
正在調用Queryable.Where()
擴展方法,而不是Enumerable.Where()
。
Enumerable.Where
返回一個枚舉,它將逐步遍歷基礎枚舉,對每個項目應用過濾器。
Queryable.Where()
的目的非常不同。 它返回一個IQueryable
,它捕獲了您正在做什么的描述。 每種方法都可以幫助您構建一個Expression Tree ,它就像一個僅被部分編譯的 lambda 函數。
IQueryable
還實現IEnumerable
。 當您開始嘗試枚舉結果時,表達式樹將被“編譯”。 因為您從DbSet
創建了IQueryable
,所以 EF Core 將接管此編譯過程。 試圖創建一個高效的 sql 語句和一個將結果轉換為對象的函數。
為了效率,這個函數和sql都會被緩存。 每次嘗試編譯相同的表達式時,都會跳過大部分編譯過程。
EF 將從您的query
對象構造一個 SQL 查詢並在服務器上執行該查詢。 這樣只返回 SQL 查詢的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.