LINQ connection using IEnumerable
constant collection
When using a LINQ JOIN clause within a SELECT statement of another JOIN statement, the error "Cannot create a constant value of type API.Models.PersonProtocol. Only primitive or enumerated types are supported in this context" occurs. This error occurs because the IEnumerable
CollectionppCombined
cannot be used as a constant value in a database context.
In the code provided:
<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>
This code attempts to concatenate data from the db.Favorites
and db.Person
tables and then projects the result into a PersonDTO
object. Within the PersonDTO
object, there is a personProtocol
property that is set to the result of a LINQ query against the ppCombined
collection.
The problem is trying to use ppCombined
as a constant value in a database context. ppCombined
is a IEnumerable
object constructed in memory, not a database table. When executing a LINQ query, it attempts to convert the personProtocol
projection into a SQL statement. However, it cannot do this because ppCombined
is not a database table or primitive type.
Solution
To resolve this error, we can fetch the filtered items in ppCombined
in memory after retrieving other attributes from the database. The following is the modified code:
<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>
In this modified code, the database query ends with the AsEnumerable()
method. This means that the rest of the operation is performed entirely in memory. Then, in a memory-based Select
projection of the anonymous object, filter the ppCombined
collection and convert it to a list.
By separating the database query from the in-memory processing, we avoid the problem of passing in-memory collections into the database context, thus solving the bug.
The above is the detailed content of How to Resolve 'Unable to create a constant value' Error in LINQ JOIN with IEnumerable Constant Collection?. For more information, please follow other related articles on the PHP Chinese website!