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

Add support for property overrides #4584

Open
PanosKousidis opened this issue Jul 10, 2024 · 7 comments
Open

Add support for property overrides #4584

PanosKousidis opened this issue Jul 10, 2024 · 7 comments
Assignees

Comments

@PanosKousidis
Copy link

PanosKousidis commented Jul 10, 2024

I have the following case:

I have a couple of classes that inherit from a base class. This is because the only difference between the classes are the property names in Cosmos. The business logic is done by using the base class object.

The following reproduces the issue

using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using Newtonsoft.Json;

public class CosmosSerializerTests
{
    [Fact]
    public void TestInheritance()
    {
        var cosmosClient = new CosmosClient(Settings.CosmosConnectionString);
        var container = cosmosClient.GetDatabase("mydb").GetContainer("myContainer");
        var query = container.GetItemLinqQueryable<ChildClass>()
            .Where(x => x.Name == "test" && x.Name2 == "test2");
        var sql = query.ToQueryDefinition().QueryText;
        Assert.Equal("SELECT VALUE root FROM root WHERE ((root[\"my_custom_child_name\"] = \"test\") " +
                     "AND (root[\"my_custom_child_name2\"] = \"test2\"))", sql);
        //Actual: "SELECT VALUE root FROM root WHERE ((root[\"my_custom_parent_name\"] = \"test\")
        //         AND (root[\"my_custom_child_name2\"] = \"test2\"
    }
    
    public class ChildClass : ParentClass
    {
        [JsonProperty("my_custom_child_name")]
        public override string? Name { get; set; }
        
        [JsonProperty("my_custom_child_name2")]
        public string? Name2 { get; set; }
    }

    public abstract class ParentClass
    {
        [JsonProperty("my_custom_parent_name")]
        public abstract string? Name { get; set; }
    }    
}

I believe the JsonProperty attributes should be read from the ChildClass in the scenario above.
Instead, it's using the parent's JsonProperty value and translates it to my_custom_parent_name instead of my_custom_child_name. The Name2 property that is not overriding anything works as expected

The above is using Newtonsoft.Json. Switching it to use System.Text.Json.Serialization:

using System.Text.Json.Serialization;

...

public class ChildClass : ParentClass
    {
        [JsonPropertyName("my_custom_child_name")]
        public override string? Name { get; set; }
        
        [JsonPropertyName("my_custom_child_name2")]
        public string? Name2 { get; set; }
    }

    public abstract class ParentClass
    {
        [JsonPropertyName("my_custom_parent_name")]
        public abstract string? Name { get; set; }
    }   

This results in no translation at all - the test result shows
SELECT VALUE root FROM root WHERE ((root["Name"] = "test") AND (root["Name2"] = "test2"))

I tried Microsoft.Azure.Cosmos 3.37.1 and 3.41.0

The alternative I have right now is to execute direct SQL text instead

@ealsur
Copy link
Member

ealsur commented Jul 11, 2024

Can you share which SDK version you are using?

@ealsur
Copy link
Member

ealsur commented Jul 11, 2024

Seems related to #4138 ?

@PanosKousidis
Copy link
Author

I just updated my original ticket description with more details

@PanosKousidis
Copy link
Author

Can you share which SDK version you are using?

Tried with 3.37.1 and 3.41.0 and the behaviour is the same

@PanosKousidis
Copy link
Author

PanosKousidis commented Jul 12, 2024

Seems related to #4138 ?

If I'm not mistaken this is about enabling System.Text.Json translation - which did not work in my example, I may be doing something wrong

@Maya-Painter
Copy link
Contributor

@PanosKousidis To enable System.Text.Json translation you need to use a custom serializer. There is an example of how to do this here: https://github.com/Azure/azure-cosmos-dotnet-v3/tree/master/Microsoft.Azure.Cosmos.Samples/Usage/SystemTextJson. Please let me know if you have any questions.

@Maya-Painter Maya-Painter self-assigned this Jul 13, 2024
@PanosKousidis
Copy link
Author

PanosKousidis commented Jul 16, 2024

Thanks @Maya-Painter , but the issue is still there.

I've drilled down and I think the behaviour I see is not Cosmos SDK-related

There is a lambda expression passed in

private static SqlScalarExpression VisitScalarExpression(LambdaExpression lambda, TranslationContext context)
{
return ExpressionToSql.VisitScalarExpression(
lambda.Body,
lambda.Parameters,
context);
}

And even though the expression itself references the ChildClass, the member referenced in "Left" is the Name property of the ParentClass instead of the ChildClass. See screenshot below

image

It is not using the declared property of the ChildClass as seen in the Expression property
image

You can probably close this ticket if you also think that there is nothing that can be done on the Cosmos SDK side to alleviate this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants