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 $type to jsonb if decorated with JsonDerivedTypeAttribute #30865

Closed
slava-se opened this issue May 10, 2023 · 3 comments
Closed

Add $type to jsonb if decorated with JsonDerivedTypeAttribute #30865

slava-se opened this issue May 10, 2023 · 3 comments

Comments

@slava-se
Copy link

I went through some relevant discussions here and my question is - is it possible to at least add $type as a discriminator to serialized jsonb or control it's addition if the class is decorated with JsonDerivedTypeAttribute? I understand that I will not be able to query on properties other that contained in the base class but could be still helpful to deserialize into proper type and avoid HasConversion(...)

My case: I'm trying to save diffferent kinds of feedbacks into the same column and the class structure uses inheritance.

    [JsonDerivedType(typeof(MyClass2), nameof(MyClass2))]
    public class MyBaseClass 
    {
        public int? MyProperty { get; set; }
    }

    [JsonDerivedType(typeof(MyClass2), nameof(MyClass2))]
    public class MyClass2 : MyBaseClass
    {
        public string? MyClassString2 { get; set; }
    }

The result of

var trans = new MyClass2 { MyClassString2 = "str2" };
var json = JsonSerializer.Serialize(trans);

contains $type as descriminator {"$type":"MyClass2","MyClassString2":"str2","MyProperty":null}.

But if I'm saving my entity to the database using EF7 serialization

    public class MyEntity
    {
        [Column(TypeName = "jsonb")]
        public MyBaseClass? MyBaseClass { get; set; }
    }

then $type is missing in the DB, retrieving the row returns the property as instance of MyBaseClass

BUT, if I manually add "$type":"MyClass2" into DB entry then the deserializer works as expected and returns the instance of MyClass2 so the EF deserializer doen't skip it, only the serializer does.

@AndriySvyryd
Copy link
Member

cc @roji

@roji
Copy link
Member

roji commented May 11, 2023

Inheritance modeling with a discriminator in EF Core's JSON support is tracked by #27779.

The above seems to be more about Npgsql's existing JSON support, which is different (npgsql/efcore.pg#2548 tracks bringing the EF JSON support over to Npgsql). When using Npgsql's support, Npgsql simply uses System.Text.Json to serialize the entire graph, so anything that System.Text.Json does by default should happen there as well; so I'm not sure why that wouldn't just work out of the box...

In any case, am closing this as external... You can open an issue on https://github.com/npgsql/efcore.pg, but I suspect most of my time on Npgsql's JSON support will be spent porting across the EF support, so I'm not sure I'll have time to investigate this...

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale May 11, 2023
@D1ssolve
Copy link

D1ssolve commented Jan 9, 2024

@slava-se did you resolve the issue ? I have a same problem

Upd:
I resolved this issue with writing typeDescriptor into db partially. Need forward params with base types into EnableDynamicJson(new[] { typeof(MyBaseClass ) });
But typeDescriptor field with metadata json writes not in first field, it becomes another issue:
The metadata property is either not supported by the type or is not the first property in the deserialized JSON object

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

5 participants