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

Added basic support for HStore operations query translation #240

Closed
wants to merge 1 commit into from

Conversation

davidkvc
Copy link

@davidkvc davidkvc commented Sep 1, 2017

I looked into how hstore support could be implemented. Some basic operations work but it is still not good enough, in my opinion, to be used properly.

When dictionary object that represents hsore column is updated it is not tracked by EF's change tracker so users would have to reassign previous value with new dictionary before every call to SaveChanges() which is not really a safe solution in my opinion.

I tried using ImmutableDictionary which would solve this problem but the serializer does not support ImmutableDictionary so we can not deserialize into it after we get data from DB.

So

  • is there a way to make EF's change tracker track changes to dictionary ?
  • can we add support for deserialization into ImmutableDictionary ?

@roji
Copy link
Member

roji commented Sep 10, 2017

@dejvid-smth just a quick message to say thanks for this PR. I'm currently too busy to properly review it but will do so as soon as I can...

Good question regarding the equality comparison for changing tracking in EF Core - I'm not sure how things work. If this is an issue, it would also be an issue for other types already supported by Npgsql (e.g. arrays). I would expect EF Core to simply execute Equals(), which would be fine for dictionaries, but I don't really know what it does. I'd recommend you post a question on the EF Core github (please link to it from here).

Am not sure that an ImmutableDictionary is a good solution for this - forcing the user to create an entire copy of the dictionary each time a change is needed is quite a poor substitute for proper change tracking.

@davidkvc
Copy link
Author

Created issue regarding change tracker not working for Dictionary<,>
dotnet/efcore#9753

@roji
Copy link
Member

roji commented Feb 17, 2018

@dejvid-smth note that EF Core has added support for custom comparison which would solve the change tracking issue mentioned here. I opened #306 to track this.


public Expression Translate(MethodCallExpression methodCallExpression)
{
if (methodCallExpression.NodeType == ExpressionType.Call

Choose a reason for hiding this comment

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

MethodCallExpression is always ET.Call? Redundant check.

public Expression Translate(MethodCallExpression methodCallExpression)
{
if (methodCallExpression.NodeType == ExpressionType.Call
&& methodCallExpression.Method.Name == "get_Item"

Choose a reason for hiding this comment

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

Should be easy to compare with actual MethodInfo rather than string name.

public Expression Translate(MethodCallExpression methodCallExpression)
{
if(methodCallExpression.Method ==
typeof(NpgsqlDbFunctionsExtensions)

Choose a reason for hiding this comment

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

store in static field to avoid doing reflection for every translation.
Same for the other If

@@ -176,6 +192,15 @@ public Expression VisitArrayAny(ArrayAnyExpression arrayAnyExpression)
return arrayAnyExpression;
}

public Expression VisitDictionaryContainsKey(DictionaryContainsKeyExpression expr)
{
Visit(expr.Dictionary);

Choose a reason for hiding this comment

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

This could be written using SqlFunctionExpression in 2.1 passing in dictionary as instance. That would avoid creating new expression type

&& typeof(IDictionary<string, string>).IsAssignableFrom(expression.Object.Type))
{
Debug.Assert(expression.Arguments.Count == 1);
var expr = Visit(expression.Object);

Choose a reason for hiding this comment

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

Same as the other. Can be SqlFunctionExpression.

@roji
Copy link
Member

roji commented Feb 19, 2018

Thanks for the review @smitpatel!

@dejvid-smth, with dotnet/efcore#9753 closed on the EF Core side, it's possible to implement proper change tracking for hstore (#306). Are you interested in continuing work on this issue for the upcoming 2.1 release? If so, please let me know and take @smitpatel's comments into account.

@davidkvc
Copy link
Author

I am currently busy with my thesis but I can get back to it in 3 months if no-one picks it up

@roji roji force-pushed the dev branch 3 times, most recently from f320396 to dfdc336 Compare February 27, 2018 15:43
@austindrenski austindrenski added the enhancement New feature or request label Jul 22, 2018
@roji
Copy link
Member

roji commented May 25, 2020

Closing this PR as stale... Many things have changed since this was submitted (notably the query pipeline rewrite for 3.0), so this would likely have to be redone.

@roji roji closed this May 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants