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

Question: json Column: support for readonly dictionaries #31607

Closed
JanEggers opened this issue Sep 1, 2023 · 6 comments
Closed

Question: json Column: support for readonly dictionaries #31607

JanEggers opened this issue Sep 1, 2023 · 6 comments

Comments

@JanEggers
Copy link

Ask a question

Im currently migrating a project from net6 to net7. we are already using jsoncolumns with ef6 but would like to migrate from

public class MyModel 
{
   public Child Child { get; set; }
}

public class Child 
{
   public IReadOnlyDictionary<string, object> CustomerExtensions { get; set; }
}

e.Property(p => p.Child).HasConersion(....);

to

e.OwnsOne(p => p.Child, p => p.ToJson());

but when trying this I encountered:

The property 'Child.CustomerExtensions' could not be mapped because it is of type 'IReadOnlyDictionary<string, object>', which is not a supported primitive type or a valid entity type.

also: having IReadOnlyDictionary<string, object> as Json Property is also not working.

Will this eventually be covered in .net 8 with primitive collection support?

Is there another way to enable json queries with the old conversion approach?

@roji
Copy link
Member

roji commented Sep 1, 2023

Duplicate of #29825

@roji roji marked this as a duplicate of #29825 Sep 1, 2023
@roji
Copy link
Member

roji commented Sep 1, 2023

No, unfortunately it's not yet possible to map Dictionary to JSON for relational databases. The upcoming EF 8 support for primitive collections is also restricted to arrays/lists, and won't support dictionaries either. Rich querying currently works only for strongly-typed mapping, i.e. where you have an actual .NET type rather than a weakly-typed dictionary.

Bottom line: for now you'll have to keep doing things as you did them in EF Core 6/7, via value conversions.

@JanEggers
Copy link
Author

thx for clarifiing

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Sep 2, 2023
@JanEggers
Copy link
Author

@roji FYI I was able to improve querying by adding a custom function mapping:

before I used:

return Items.FromSqlInterpolated($"SELECT * FROM Items WHERE JSON_VALUE(Extension, '$.value') = {value}");

with this function mapping:

onModelCreating() {

            modelBuilder.HasDbFunction(typeof(DbContext).GetMethod(nameof(JsonValue), new[] { typeof(string), typeof(string) }))
                .HasTranslation(args => new SqlFunctionExpression("JSON_VALUE", args, true, new [] { false, false }, typeof(string), null));
}

        public string JsonValue(string expression, string path)
        {
            throw new NotSupportedException();
        }

i can use this query which is much better because less of the query is hardcoded string

return Items.Where(sh => JsonValue((string)(object)sh.Extension, "$.value") == value);

@roji
Copy link
Member

roji commented Sep 4, 2023

@JanEggers yeah, you can enable this very limited form of querying - but you won't be able to do various other types of querying, e.g. the collection querying support which we're adding in EF 8.0. But if this partial solution is sufficient for you, it's definitely fine.

@palhal
Copy link

palhal commented Mar 1, 2024

return Items.Where(sh => JsonValue((string)(object)sh.Extension, "$.value") == value);

Wow, that was clever @JanEggers. Exactly what I needed until dictionaries are supported first class. Thanks!

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