is it possible to store recursive data types as json column?
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
### Include your code
I have class that can contain it self or other types that can contain that same class, is it possible to store this type as json in a column with ef core?
I'd expect to have something like:
```cs
modelBuilder.Entity()
.OwnsMany(
x => x.Components,
navBuilder => navBuilder.ToJsonTheWhoooooleDamnThing()
);
```
instead I have to configure each navigation manually, but
- if configuring navigations of types which have already been configured - exception is thrown
- if not configuring these navigations data is incorrectly stored in the databse
- furthermore, included a screenshot, for some reason ef core attached the parent object to the child property
Sample:
```C#
using Microsoft.EntityFrameworkCore;
{
var appDbContext = new AppDbContext();
appDbContext.Database.EnsureDeleted();
appDbContext.Database.EnsureCreated();
appDbContext.Products.Add(new Product()
{
Name = "test",
Components =
[
new Component() { Name = Guid.NewGuid().ToString() },
new Component()
{
Side = new Component() { Name = Guid.NewGuid().ToString() },
Name = Guid.NewGuid().ToString(),
},
new Component()
{
Name = Guid.NewGuid().ToString(),
Components =
[
new Component()
{
Name = Guid.NewGuid().ToString(),
Side = new Component() { Name = Guid.NewGuid().ToString(), Components = [] },
},
new Component() { Name = Guid.NewGuid().ToString() },
new Component() { Name = Guid.NewGuid().ToString() }
]
},
],
});
appDbContext.SaveChanges();
}
{
var appDbContext = new AppDbContext();
var products = appDbContext.Products.ToList();
Console.WriteLine(products);
}
public class AppDbContext : DbContext
{
public DbSet Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("...");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity()
.OwnsMany(
x => x.Components,
navBuilder =>
{
navBuilder.ToJson();
navBuilder.OwnsMany(x => x.Components);
// can't configure further, exception is thrown
// navBuilder.OwnsMany(x => x.Components, builder =>
// {
// builder.OwnsMany(x => x.Components);
// builder.OwnsOne(x => x.Side);
// });
navBuilder.OwnsOne(x => x.Side);
}
);
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public List Components { get; set; }
}
public class Component
{
public string Name { get; set; }
public List Components { get; set; }
public Component Side { get; set; }
}
```
Stored json:
```json
[
{
"Name": "4741f8a5-b7eb-4f1a-ad89-67654d305199",
"Side": null,
"Components": null
},
{
"Name": "8077e443-cdd3-4746-97fa-c40d33e12686",
"Side": {
"Name": "a35dc642-fe01-43fb-86f2-01c3b87f3734"
},
"Components": null
},
{
"Name": "4651ee19-3215-46c0-9e20-0fafd62fbc25",
"Side": null,
"Components": [
{
"Name": "886583d3-4cca-4abf-87a0-65b8a41ab8e1"
},
{
"Name": "6aa899eb-0d14-4ecf-9f1f-95c9b61d5620"
},
{
"Name": "aeefadac-817f-44c1-84b0-d154423896ca"
}
]
}
]
```
retrieved data:
### Include provider and version information
EF Core version: 8.0.2
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 8.0.2
Target framework: .NET 8.0
Operating system: 14.2.1 (23C71)
IDE: Rider 2024.1.1
Contributor guide
Assessment
This issue has not been assessed yet.