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

Allow mapping JSON to Dictionary<string,string> #1825

Open
sneltyn opened this issue Apr 26, 2021 · 9 comments
Open

Allow mapping JSON to Dictionary<string,string> #1825

sneltyn opened this issue Apr 26, 2021 · 9 comments
Labels
enhancement New feature or request
Milestone

Comments

@sneltyn
Copy link

sneltyn commented Apr 26, 2021

Hello! I have question. I used next entity with jsonb type column:

class Entity
{
    public int Id {get;set;}
    
    [Column(TypeName = "jsonb")]
    public Dictionary<string, string> Name {get;set;}  
}

I want to use order by for example how Postgres SQL script:

SELECT "Id", "Name" FROM public."Entities" ORDER BY "Name"->>'en' DESC

Is it possible to do this sorting on EF? I searched in the documentation for this, as well as on the vastness of stackoverflow and in issues github, but I did not find an answer to this question.

@roji roji changed the title Order by jsonb for key Allow mapping JSON to Dictionary<string,string> Apr 26, 2021
@roji
Copy link
Member

roji commented Apr 26, 2021

The provider currently doesn't support mapping Dictionary<string,string> to JSON; you can either map a .NET POCO (for strongly-typed documents with a fixed schema) or JsonDocument (for weakly-typed documents with varying schemas). See the docs for more details. If you use one of these two mapping techniques, you can generate a JSON field lookup in an ORDER BY just as you would in a WHERE clause.

Keeping open to track mapping Document<string,string>.

@roji roji added the enhancement New feature or request label Apr 26, 2021
@roji roji added this to the Backlog milestone Apr 26, 2021
@rlightner
Copy link

@roji Any chance there was movement on this since 2021, or a way to implement this?

@roji
Copy link
Member

roji commented Aug 7, 2023

@rlightner the main reason I haven't been looking at this is the steady progress on JSON support at the EF side - it would be best to not do something specific here on the PG side but rather to have one holistic approach across EF. For now, you can use value converters to serialize your Dictionary to a JSON document, and then use SQL querying if you need to query inside that document.

@rlightner
Copy link

Thanks for the fast response. To clarify:
Something like this?

    [Column("key_values", TypeName = "jsonb")]
    public Dictionary<string, string> KeyValues{ get; set; }
                entity.Property(p => p.KeyValues)
                      .HasColumnType("jsonb")
                      .HasConversion(
                        v => JsonSerializer.Serialize(v, new JsonSerializerOptions(JsonSerializerDefaults.General)),
                        v => JsonSerializer.Deserialize<Dictionary<string, string>>(v, new JsonSerializerOptions(JsonSerializerDefaults.General))!);

@roji
Copy link
Member

roji commented Aug 7, 2023

Yep - that should take care of serialization. The only thing this doesn't take care of is querying (e.g. filtering based on the value inside the dictionary).

@totpero
Copy link

totpero commented Nov 30, 2023

I use something like this for Dictionary<string, string>:

builder.OwnsOne(
    q => q.Name, ownedNavigationBuilder =>
    {
        ownedNavigationBuilder.ToJson("jsonb");
        ownedNavigationBuilder.Ignore(x => x.Capacity);
        ownedNavigationBuilder.Ignore(x => x.Count);
    });

@roji
Copy link
Member

roji commented Nov 30, 2023

Note that mapping Dictionaries is not support when using ToJson and Owns (see dotnet/efcore#29825).

@avisra
Copy link

avisra commented Jun 12, 2024

@roji I'm just now getting around to upgrading my project to .NET 8.

I see that POCO mapping was deprecated. Am I correct in my understanding that this means I can no longer use [Column(TypeName = "jsonb")] on collections? Is there a way to continue using it for things like this? I was using the [Column(TypeName = "jsonb")] for dictionaries just fine, but due to the deprecation, had to switch most things to ToJson. And now I'm in refactoring hell due to bugs in .NET 8 (e.g. the Id property bug) and missing features in .NET 8 like this dictionary support missing

@roji
Copy link
Member

roji commented Jun 12, 2024

The older way of mapping JSON via [Column(TypeName = "jsonb")] isn't deprecated, where are you seeing that it can "no longer be used"? This method is just no longer the recommended way going forward. When something isn't supported via ToJson() - like weakly-typed mapping via Dictionary, using [Column(TypeName = "jsonb")] should be fine.

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

No branches or pull requests

5 participants