Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ReadItem for no-tracking queries #33927

Merged
merged 3 commits into from
Jun 15, 2024
Merged

Support ReadItem for no-tracking queries #33927

merged 3 commits into from
Jun 15, 2024

Conversation

ajcvickers
Copy link
Member

Part of #20693
Part of #33893

There is a lot left to do here, but I'm making a break here to get reviews before it goes too far.

Major changes here are:

  • Discover and record properties used to form the JSON id in one place.
  • Use this to generate ate id values without tracking an instance. (Makes no-tracking work, needed for Reload.)
  • Be better at detecting only detecting patterns we can later translate.

Next up: be better at detecting non-Find query patterns that we can translate.

@ajcvickers ajcvickers requested a review from a team June 7, 2024 14:07
src/EFCore.Cosmos/Metadata/Conventions/JsonIdConvention.cs Outdated Show resolved Hide resolved
src/EFCore.Cosmos/Metadata/Internal/JsonIdDefinition.cs Outdated Show resolved Hide resolved
@@ -92,8 +93,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
[return: NotNullIfNotNull(nameof(expression))]
public override Expression? Visit(Expression? expression)
{
if (_queryCompilationContext.QueryTrackingBehavior == QueryTrackingBehavior.TrackAll // Issue #33893
&& expression is MethodCallExpression
if (expression is MethodCallExpression
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not quite related to this PR)

This being in Visit() means that it's done recursively for every node - although we should only pattern-match on the top-level node. In other words, if the whole ReadItem-compatible fragment is composed upon with something, we probably incorrectly convert (and have a bug). To fix this, we should override QueryableMethodTranslatingExpressionVisitor.Translate() and have it there.

As a nit, I'd also move the logic to a dedicated function (TryTransformToReadItem) just to make it extra clear what's being done here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ajcvickers noticed this again while working in an area of the code; opened #34085 to make sure we don't forget it.

}
else
{
Check.DebugFail("Parameters should cover all properties or we should not be using ReadItem.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I've switched to throwing UnreachableException in these cases, since Check.DebugFail is for DEBUG-only, i.e. to get the assertion to trip in actual released bits (but not super important).

@ajcvickers
Copy link
Member Author

@AndriySvyryd @roji There is a meta point that probably should be discussed here. In current versions of the Cosmos provider, a user can put their own value generator on the id property and in doing so change the way we build the composite key string. If we hard-code (that is remove the code from a convention and remove the factory that creates the definition) then everything here gets simpler. But it means that people can no longer customize this if they need to. (I'm not sure they need to--but this goes to the discussion about how much we can break things that can work now. We have tests that do this customization, so at some point we thought it important enough to test.)

@roji
Copy link
Member

roji commented Jun 12, 2024

@ajcvickers yeah, understood. We should maybe have a discussion on this in design...

@AndriySvyryd
Copy link
Member

@ajcvickers Users can still use their implementation of IRuntimeJsonIdDefinitionFactory if they need to customize this.

@ajcvickers
Copy link
Member Author

@AndriySvyryd @roji New version up based on Andriy's suggestion.

protected override void InitializeModel(IModel model, bool designTime, bool prevalidation)
{
base.InitializeModel(model, designTime, prevalidation);
model.SetRuntimeAnnotation(CosmosAnnotationNames.ModelDependencies, CosmosDependencies);
Copy link
Member

@AndriySvyryd AndriySvyryd Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only set this if prevalidation is true or false

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndriySvyryd

Only set this if prevalidation is true or false

prevalidation is a non-nullable bool...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only set it when it's true xor false.
Basically, only do it once.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndriySvyryd I'm obviously missing something fundamental here. prevalidation is a single bool value. What am I xoring that with?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C# is more precise than English. Add this after the first line:

if (!prevalidation)
{
    return;
}

Part of #20693
Part of #33893

There is a lot left to do here, but I'm making a break here to get reviews before it goes too far.

Major changes here are:
- Discover and record properties used to form the JSON `id` in one place.
- Use this to generate ate `id` values without tracking an instance. (Makes no-tracking work, needed for Reload.)
- Be better at detecting only detecting patterns we can later translate.

Next up: be better at detecting non-Find query patterns that we can translate.
@ajcvickers ajcvickers merged commit 0fe066c into main Jun 15, 2024
7 checks passed
@ajcvickers ajcvickers deleted the PrettyLittleKeys branch June 15, 2024 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants