以下linq2entities代碼似乎會調用FirstOrDefault擴展的IEnumerable版本,因爲PersonHistories是一個ICollection。但是在運行時,它實際上調用了IQueryable版本。隱式AsQueryable
var test = db.Persons.Where(d => d.PersonKey == 4)
.Select(f => f.PersonHistories.FirstOrDefault());
我遇到的問題是,我使用的是不執行該自動轉換的自定義查詢供應商,我得到的錯誤「...的ICollection不能被用於類型的IQueryable的參數」。因此,需要顯式調用AsQueryable已到解決這個問題,但對於複雜的查詢,它會非常多餘的,不是感覺很乾:
db.Persons.Where(d => d.PersonKey == 4)
.Select(f => f.PersonHistories.AsQueryable().FirstOrDefault());
我已經在框架參考源周圍挖試圖找到LINQ的2實體訪客/供應商東西,但沒有運氣(也許不是任何開放參考資源的一部分)。 基礎提供者如何完成AsQueryable的這種隱式使用?
我明白,這些被翻譯成表達式樹。 我明白,提供者將Enumerable.FirstOrDefault替換爲Queryable.FirstOrDefault。這是問題的前提。
嘗試翻轉它,並看到它「只是工作」:'db.Persons.Where(d => d.PersonKey == 4).PersonHistories.FirstOrDefault()' – bluevector
不,不起作用,因爲.Where返回一個集合/ IQueryable,其上沒有這樣的PersonHistories字段。你將不得不使用類似SingleOrDefault的東西來獲取單個項目,或者使用.Select來投影嵌套字段。我選擇用嵌套投影演示問題,因爲這是我遇到問題的地方。由於db.Persons是一個DbSet,因此它是IQueryable,因此.Where自動成爲IQueryable版本,但相比之下,Person.PersonHistories作爲ICollection實現,處理起來更具挑戰性。 – AaronLS