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

Navigation in owned JSON entity #32137

Closed
HppZ opened this issue Oct 23, 2023 · 5 comments
Closed

Navigation in owned JSON entity #32137

HppZ opened this issue Oct 23, 2023 · 5 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@HppZ
Copy link

HppZ commented Oct 23, 2023

class A // has table in db
{
    public long Id { get; set; }
    public List<B> Items { get; set; }
}

class B // no table in db
{
    public C Definition { get; set; }
    public string Property1 { get; set; }
}

class C // has table in db
{
    public long Id { get; set; }
    public string Property2 { get; set; }
}

I want to store A.Items as JSON, preserving the properties Property1 of B and Id of C when serializing Items. When querying object A, I want to be able to use the preserved Id property of C in the JSON to retrieve object C and assign it to the Definition field of B.

@roji
Copy link
Member

roji commented Oct 23, 2023

It seems like you're asking for an owned JSON entity (B) to have a navigation out to an entity outside the document (C), which is mapped to its own table. This currently isn't supported.

As a workaround, you can store the Id of C inside B directly as a foreign key (i.e. as a long), and then use LINQ Join to fetch C in the same query.

@HppZ
Copy link
Author

HppZ commented Oct 24, 2023

1, Will that be supported in the future?
2, Could you please show me some sample code?

@HppZ HppZ changed the title How to do this conversion? Navigation in owned JSON entity Oct 24, 2023
@ajcvickers
Copy link
Contributor

@HppZ Sorry for taking a long time to respond. 1. is tracked by #31245. 2. Do you still need some sample code?

@HppZ
Copy link
Author

HppZ commented Jan 19, 2024

That would be great if you're willing!

@roji
Copy link
Member

roji commented Jan 31, 2024

Sorry for taking so long to reply with a sample. What you're trying to achieve should be doable via the following:

_ = await ctx.A
    .Select(a => new
    {
        A = a,
        Definitions = ctx.C
            .Where(c => a.Items.Select(b => b.DefinitionId).Contains(c.Id))
            .ToList()
    })
    .ToListAsync();

In other words, for each A, query out the rows from C whose Id is in the list of definition IDs from inside A's B.

Full code sample
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();

_ = await ctx.A
    .Select(a => new
    {
        A = a,
        Definitions = ctx.C
            .Where(c => a.Items.Select(b => b.DefinitionId).Contains(c.Id))
            .ToList()
    })
    .ToListAsync();

public class BlogContext : DbContext
{
    public DbSet<A> A { get; set; }
    public DbSet<C> C { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<A>()
            .OwnsMany(a => a.Items, a => a.ToJson());
    }
}

public class A // has table in db
{
    public long Id { get; set; }
    public List<B> Items { get; set; }
}

public class B // no table in db
{
    public string Property1 { get; set; }

    // public C Definition { get; set; }
    public int DefinitionId { get; set; }
}

public class C // has table in db
{
    public int Id { get; set; }
    // public long Id { get; set; }
    public string Property2 { get; set; }
}

The issue tracking allowing navigations out of a complex type is #31245. We can keep this issue for tracking doing the same, if we believe we'll end up doing the same for owned entity types.

@roji roji removed their assignment Jan 31, 2024
@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Feb 8, 2024
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

3 participants