使用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中文网其他相关文章!