Work on Cosmos primitive collections, subquery and general query infra#33895
Work on Cosmos primitive collections, subquery and general query infra#33895roji merged 1 commit intodotnet:mainfrom
Conversation
Implements dotnet#25701 for primitive collections Implements dotnet#25700 for primitive collections Largely implements dotnet#25765 Fixes dotnet#33858
| /// any release. You should only use it directly in your code with extreme caution and knowing that | ||
| /// doing so can result in application failures when updating to a new Entity Framework Core release. | ||
| /// </summary> | ||
| protected override bool ShouldConvertToInlineQueryRoot(Expression expression) |
There was a problem hiding this comment.
At some point we should consider switching the default for primitive collections. This would be a breaking change for existing non-relational providers, which would have to opt out.
There was a problem hiding this comment.
Doesn't seem like it would provide enough value to justify the braking change
|
|
||
| // TODO: Should the type be an array, or enumerable/queryable? | ||
| var arrayClrType = projection.Type.MakeArrayType(); | ||
| // TODO: Temporary hack - need to perform proper derivation of the array type mapping from the element (e.g. for |
There was a problem hiding this comment.
@ajcvickers we need to implement getting the array type mapping from its element, including value converters etc. (like in relational)
| { | ||
| // TODO: the below immediately wraps the JSON array property in a subquery (SELECT VALUE i FROM i IN c.Array). | ||
| // TODO: This isn't strictly necessary, as c.Array can be referenced directly; however, that would mean producing a | ||
| // TODO: ShapedQueryExpression that doesn't wrap a SelectExpression, but rather a KeyAccessExpression directly; this isn't currently |
There was a problem hiding this comment.
@ajcvickers note yet another case where SelectExpression gets in the way
| && (convertedType == null | ||
| || convertedType.IsAssignableFrom(ese.Type))) | ||
| { | ||
| // TODO: Subquery projecting out an entity/structural type |
There was a problem hiding this comment.
Scalar subqueries are implemented for primitives, but not yet for structural types - that's coming.
| private const string RootAlias = "c"; | ||
|
|
||
| private IDictionary<ProjectionMember, Expression> _projectionMapping = new Dictionary<ProjectionMember, Expression>(); | ||
| private readonly List<SourceExpression> _sources = []; |
There was a problem hiding this comment.
This starts to add infra for multiple sources in a Cosmos query (e.g. joins), but at this point we only actually support a single one (enforced in CosmosQuerySqlGenerator)
| private CoreTypeMapping? FindCollectionMapping(in TypeMappingInfo mappingInfo) | ||
| { | ||
| var clrType = mappingInfo.ClrType!; | ||
| var elementMapping = mappingInfo.ElementTypeMapping; |
There was a problem hiding this comment.
@ajcvickers this is the type mapping side of the primitive collection support - first the new EF 8.0 primitive collection thing, then the Cosmos-specific dictionary mapping support.
| AssertSql( | ||
| """ | ||
| SELECT VALUE {"Value" : ((c["Discriminator"] = "Kiwi") ? c["FoundOn"] : 0)} | ||
| SELECT VALUE |
There was a problem hiding this comment.
Did some SQL style changes: when we project using JSON object style, we break lines. When there's only one property being projected, we prefer "x AS y" and not object style, but in some cases we still must use object style (AS style isn't supported with "Value").
|
Thanks for the review @AndriySvyryd (it's a good way to also shame me into reviewing #33747 ;)). @ajcvickers @cincuranet @maumar I'll go ahead and merge to not block progress, but definitely take a look if you have a moment - I can correct problems in further PRs.
I'm going to be continuing work on all this part in the coming days - I've got my personal list to track the work, would rather not span the repo with micro-issues etc... |
This is the 1st PR doing work on the Cosmos pipeline; the main goal here is to support primitive collections, but this also brings in lots of other necessary query infra, modernizes the pipeline and aligns it with latest best practices and relational. Subsequent PRs should be smaller/more incremental.
This PR leaves certain things unimplemented which I intend to work on very soon (to avoid one huge PR), not everything is tracked via issues (but I have my own list etc.).
Implements #25701 for primitive collections
Implements #25700 for primitive collections
Largely implements #25765
Fixes #33858