我是 Entity Framework 的新手,想對某些事情進行一些澄清。我理解DbContext諸如指向帶有連接字串的 SQL 資料庫之類的。在 中DbContext,您宣告DbSet<perEachTable>您希望/計劃從所述 SQL 資料庫公開和獲取資料。
現在,您進入 LINQ,我了解了一些鏈接,例如可列舉的事物串列和尋找某些符合條件的 where 條件條目。
現在,我更大的問題以及 EF 如何查詢。你有一個DbContext指向 SQL Server。它有一張有 25 萬客戶的桌子。它的主鍵定義為Id(或CustomerId),這是預期的。您想根據用戶的電子郵件地址查詢和查找客戶(預期查詢的常見型別)。客戶表在電子郵件上有一個索引。
在我看到的 LINQ 查詢中,它指的DbSet是任何表并運行 where 子句,例如
using (var context = new DBCustomers())
{
var query = context.Customer
.Where(c => c.EMail == "[email protected]")
.FirstOrDefault<Customer>();
}
我的想法是整個客戶串列都被從它的 DbSet 背景關系中拉下來了。然后它運行鏈接WHERE子句來查找電子郵件。我不認為我想每次都減少 250k 客戶只是為了 LINQ 迭代他們。
它WHERE實際上并沒有使用客戶的整個資料集(尤其是當它繼續增長時)并且只是基于可用的索引進行優化并且實際上并沒有將所有內容都拉下來,這是怎么回事。
這是否只是一個正在應用的魔法黑盒,EF 只是將符合條件的最終條目交給您(或者如果其他更開放的查詢則很少)。
我還看到了使用完全撰寫的 SQL 陳述句和引數化的 EF Core 實體,這是我更習慣做的事情。讓 SQL Server 引擎根據與合格索引最匹配的顯式條件回傳資料。
感謝對基礎操作的澄清。
uj5u.com熱心網友回復:
我不是 EF 方面的專家,但不要求整張桌子。
它不回傳一個IEnumerable但IQueryable它會根據 linq 陳述句生成一個 SQL 查詢,并在它被迭代時在 sql-server 上執行它(例如 foreach 回圈)。
您可以使用以下方法獲取 SQL 查詢:
var query = context.Customer.Where(x => x.Id == 1);
Console.WriteLine(query.ToQueryString());
uj5u.com熱心網友回復:
您的代碼DbSet<T>.Where()正在呼叫Queryable.Where()擴展方法,而不是Enumerable.Where().
Enumerable.Where回傳一個列舉,它將逐步遍歷基礎列舉,對每個專案應用過濾器。
的目的Queryable.Where()是非常不同的。它回傳一個IQueryable捕獲你正在做什么的描述。每種方法都可以幫助您構建一個Expression Tree,它就像一個僅被部分編譯的 lambda 函式。
AnIQueryable也實作了IEnumerable. 當您開始嘗試列舉結果時,運算式樹將被“編譯”。因為您是IQueryable從 a創建的DbSet,所以 EF Core 將接管此編譯程序。試圖創建一個高效的 sql 陳述句和一個將結果轉換為物件的函式。
為了效率,這個函式和sql都會被快取。每次嘗試編譯相同的運算式時,都會跳過大部分編譯程序。
uj5u.com熱心網友回復:
EF 將從您的query物件構造一個 SQL 查詢并在服務器上執行該查詢。這樣只回傳 SQL 查詢的結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493669.html
上一篇:連接列根據條件分布在多行中
