Есть ли способ использовать список с EF Core Postgres JSON? - PullRequest
0 голосов
/ 27 марта 2020

Это возможно в PG:

public class Parent
{
  [Column(TypeName = "jsonb")]
  //Mode 1: a column in the table
  public Child[] Children { get; set; }
}

public class Child
{
  //Mode 2: a virtual column only existing in JSON
  public GrandChild[] GrandChildren { get; set; }
}

public class GrandChild
{
}

У меня вопрос, есть ли способ использовать другие типы CLR inline, вместо массивов, таких как List<T>, HashSet<T> или даже просто * 1006? * или ICollection<T>, чтобы обеспечить легкий доступ и избегать воссоздания коллекции каждый раз, когда мы хотим внести изменения, или избежать определения множества других свойств прокси.

Я попытался установить HasConversion в массив, но он не работал.

1 Ответ

1 голос
/ 27 марта 2020

Работает "автоматически", если вы включаете type plugins в Npgsql.Json.NET:

NpgsqlConnection.GlobalTypeMapper.UseJsonNet();
using (var context = new MyContext(options.Options))
{
    var parent = new Parent()
    {
        Children = {
            new Child() {
                GrandChildren = {
                    new GrandChild() { Name = "A" },
                    new GrandChild() { Name = "B" }
                }
            }
        }
    };

    context.Add(parent);
    context.SaveChanges();

    foreach(var p in context.Parents.ToList()) {
        // This is just to print the whole object. You don't have to touch JSON.NET
        // yourself here, Npgsql will convert to/from .net types at 'the edges'.
        Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(p));
    }       
}


// Using these definitions
class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> options)
       : base(options)
    { } 
    public DbSet<Parent> Parents { get; set; }
}
public class Parent
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Column(TypeName = "jsonb")]
    public List<Child> Children { get; set; } = new List<Child>();
}    
public class Child
{
    public List<GrandChild> GrandChildren { get; set; } = new List<GrandChild>();
}    
public class GrandChild
{
    public string Name { get; set; }
}
...