You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When creating a LINQ query that includes a field that is calculated in the projection it results in an exception depending on the order of fields in the projection.
Cause analysis
Observed behaviour:
It appears fields calculated in the projection will use field name c, c0, c1, etc.
If a nested collection is requested projection will include the entire object instead of projecting only the required fields (known limitation of EF for cosmos).
The root in the query has alias c (in SQL), but it is treated as a calculated field so in the result it is mapped to fields named c, c0, c1, etc depending on the position in the query.
Based on the error and the fact that changing the order affects the outcome it appears that during deserialization the object used for nested collection is always expected to be in a field named c.
Message:
Newtonsoft.Json.JsonSerializationException : Deserialized JSON type 'Newtonsoft.Json.Linq.JValue' is not compatible with expected type 'Newtonsoft.Json.Linq.JObject'. Path 'c'.
Stack Trace:
JsonSerializerInternalReader.CreateJToken(JsonReader reader, JsonContract contract)
JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
JsonSerializer.Deserialize(JsonReader reader, Type objectType)
JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
lambda_method382(Closure , QueryContext , JObject )
Enumerator.MoveNext()
Example.WithNestedFails() line 51
When using LINQ pad on the same model (from a dll) the exception type and stacktrace are slightly different but otherwise the behaviour is the same.
Note that this is the behaviour we see in or environment when
Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'.
at lambda_method339(Closure , QueryContext , JObject )
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable`1.Enumerator.MoveNext()
Error from our test environment:
System.InvalidCastException: Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'.
at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.SafeToObjectWithSerializer[T](JToken token)
at lambda_method2651(Closure , QueryContext , JObject )
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
Include verbose output
When extracting the SQL as generated by Entity Framework it looks like the problem is caused by the naming of calculated fields in the query.
Failing example
SELECT VALUE {"c" : ((c["Status"] = 2) ? "a" : "b"), "c0" : c}
FROM root c
Successful
SELECT VALUE {"c": c, "c0" : ((c["Status"] = 2) ? "a" : "b")}
FROM root c
Include provider and version information
EF Core version:
Database provider: Microsoft.EntityFrameworkCore.Cosmos (7.0.12)
Target framework: .NET 6.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.6.4
The text was updated successfully, but these errors were encountered:
AndriySvyryd
changed the title
InvalidCastException JValue to JObject when using calculated fields
Incorrect naming of calculated values in projections
Oct 11, 2023
File a bug
When creating a LINQ query that includes a field that is calculated in the projection it results in an exception depending on the order of fields in the projection.
Cause analysis
Observed behaviour:
c
,c0
,c1
, etc.root
in the query has alias c (in SQL), but it is treated as a calculated field so in the result it is mapped to fields namedc
,c0
,c1
, etc depending on the position in the query.Based on the error and the fact that changing the order affects the outcome it appears that during deserialization the object used for nested collection is always expected to be in a field named
c
.Include your code
Repository with reproduction: https://github.com/grassgit/repro-efcosmos
This code is the core of the issue:
This fails:
Switching the order of the fields makes it work:
Include stack traces
From the test project:
When using LINQ pad on the same model (from a dll) the exception type and stacktrace are slightly different but otherwise the behaviour is the same.
Note that this is the behaviour we see in or environment when
Error from our test environment:
Include verbose output
When extracting the SQL as generated by Entity Framework it looks like the problem is caused by the naming of calculated fields in the query.
Failing example
Successful
Include provider and version information
EF Core version:
Database provider: Microsoft.EntityFrameworkCore.Cosmos (7.0.12)
Target framework: .NET 6.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.6.4
The text was updated successfully, but these errors were encountered: