使用IEnumerable
常數集合的LINQ連接
在另一個JOIN語句的SELECT語句中使用LINQ JOIN子句時,會發生錯誤「無法建立API.Models.PersonProtocol類型的常數值。此上下文中僅支援基元類型或枚舉類型」。此錯誤是因為IEnumerable
集合ppCombined
不能用作資料庫上下文中的常數值。
在提供的程式碼中:
<code class="language-csharp">var persons = db.Favorites .Where(x => x.userId == userId) .Join(db.Person, x => x.personId, y => y.personId, (x, y) => new PersonDTO { personId = y.personId, addressId = y.addressId, favoriteId = x.favoriteId, personProtocol = (ICollection<PersonProtocol>) ppCombined .Where(a => a.personId == x.personId) .Select( b => new PersonProtocol() { personProtocolId = b.personProtocolId, activateDt = b.activateDt, personId = b.personId }) });</code>
這段程式碼嘗試連接db.Favorites
和db.Person
表中的數據,然後將結果投影到PersonDTO
物件中。在PersonDTO
物件中,有一個personProtocol
屬性,該屬性設定為針對ppCombined
集合的LINQ查詢的結果。
問題在於嘗試在資料庫上下文中使用ppCombined
作為常數值。 ppCombined
是在記憶體中建構的IEnumerable
對象,而不是資料庫表。當執行LINQ查詢時,它會嘗試將personProtocol
投影轉換為SQL語句。但是,它無法執行此操作,因為ppCombined
不是資料庫表或基元類型。
解
為了解決此錯誤,我們可以在從資料庫檢索其他屬性後,在記憶體中提取ppCombined
中過濾後的項目。以下是修改後的程式碼:
<code class="language-csharp">var persons = db.Favorites .Where(f => f.userId == userId) .Join(db.Person, f => f.personId, p => p.personId, (f, p) => new // 匿名对象 { personId = p.personId, addressId = p.addressId, favoriteId = f.favoriteId, }) .AsEnumerable() // 数据库查询在此结束,其余部分是在内存中进行的查询 .Select(x => new PersonDTO { personId = x.personId, addressId = x.addressId, favoriteId = x.favoriteId, personProtocol = ppCombined .Where(p => p.personId == x.personId) .Select(p => new PersonProtocol { personProtocolId = p.personProtocolId, activateDt = p.activateDt, personId = p.personId }) .ToList() });</code>
在此修改後的程式碼中,資料庫查詢以AsEnumerable()
方法結束。這意味著其餘操作完全在記憶體中執行。然後,在匿名物件的基於記憶體的Select
投影中,過濾ppCombined
集合並將其轉換為列表。
透過將資料庫查詢與記憶體中的處理分開,我們避免了將記憶體集合傳遞到資料庫上下文中的問題,從而解決了該錯誤。
以上是如何解決 LINQ JOIN 與 IEnumerable Constant Collection 中的「無法建立常數值」錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!