Skip to content

Map related entities for JSON columns as owned by convention #30963

@xevilmaxx

Description

@xevilmaxx

Ask a question

If i didn't misunderstood.
Based on class structure below, to represent LanguageResource_Table i would need to have context similar too:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<LanguageResource_Table>(e =>
            {
                e.OwnsOne(x => x.Data, ownedNavigationBuilder =>
                {
                    ownedNavigationBuilder.ToJson();
                    ownedNavigationBuilder.OwnsMany(si => si.Resources);
                });
            });

        }

Where i use .OwnsOne(...) | .OwnsMany(...) to represent object's sub-objects.
If i don't do that, during migration creation i get an error becouse some types are not mapped to CLR or something similar.

What if don't want to care about the strucutre of the object, can i avoid to use: OwnsOne/OwnsMany?
I mean i tried same class structure with Ngpl (postgres) specific client (always EF Core version) and in that case i just needed to add a Data annotation above "Data" field and it was able automatically map all sub-objects to and from DB, no even need to touch OnModelCreating (even if there was a FluentAPI method that does something similar it would be already great).

In my particular case i suppose that my POCO object may evolve over time and in some cases there might be a decent amount of sub-classes and i don't want to map them manually in the context each time.

If its not an option, do you think there is a chance to use reflection in order to build those OwnsOne / OwnsMany on runtime?
I made a fast try but without much success.

I also want to avoid to use JsonObject if its still there becouse i want to see object transparently and access its properties without using string search during LINQ queries. Like:

using (var db = DbFactory.GetContext())
{
    var x = db.LanguageResource_Table.Where(x => x.Data.Language == "en").ToList();
}

Include your code

public class LangRes
    {
        public string Key { get; set; }
        public string Value { get; set; }
        public string Description { get; set; }
    }

public class LanguageResource
    {
        public long Id { get; set; }
        public string Language { get; set; }
        public List<LangRes> Resources { get; set; }
    }

public class LanguageResource_Table
    {

        public long Id { get; set; }

        //[Column(TypeName = "jsonb")] - postgres client specific annotation
        public LanguageResource Data { get; set; }

    }

Include stack traces

Include verbose output

Include provider and version information

EF Core version: 8 preview 3
Database provider: Microsoft.EntityFrameworkCore.SqLite
Target framework: NET 7.0
Operating system:
IDE: Visual Studio 2022 17.5

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions