Entity Framework Core - Join do widoku

1

Przedstawię problem szerzej, żeby nie wyszedł XY Problem.
Mam taką sytuację:

public class A
{
    public long Id { get; set; }
    public long BId { get;set; }
    public B B { get; set;}
}

public class B
{
    public long Id { get; set; }
    public string Json {get; set;}
}

W polu w B znajduje się stosunkowo duży JSON. Baza to Postgres, umożliwiający query'owanie JSONów po stronie bazy. Załóżmy dla uwagi, że potrzebujemy jedno wybrane property z tego JSONa, co dałoby się zrobić jakoś w stylu SELECT a.*, b.Json ->> 'prop' from A a LEFT JOIN B b on a.BId = b.Id.

Pomysł pierwszy (z tytułu tematu):
tworzę widok na tą drugą tabelę wyciągając interesujące property z intecją robienia JOIN do tego widoku, zmieniam klasę A na

public class A
{
    public long Id { get; set; }
    public long BId { get;set; }
    public B B { get; set;}
    public C C { get; set;}
}

public class C
{
    public long Id { get; set; }
    public string Prop { get;set; }
}

i chciałbym łączyć to po tym samym kluczu, tj. A.BId = C.Id

Niestety, za żadne skarby nie udało mi się dojść do konfiguracji, w której Include(x => x.C) działa.

Pomysł drugi:
dodaję do B computed columns i nie mapuję w ogóle Json, ale niespecjalnie podobają mi się Postgresowe stored generated columns i wolałbym ich uniknąć. Czy ktoś kojarzy opcję do zmuszenia EF do modfikowania SELECT tak, żeby to generowanie występowało tam, tj. żeby odwołanie do Prop generowało SELECT Json ->> 'prop'. W grę wchodzi oczywiście samodzielne wrzucenie tego fragmentu jako surowy SQL.

Wołam mastera EF @WeiXiao

3

A to patrzyłeś?

https://www.npgsql.org/efcore/mapping/json.html?tabs=data-annotations%2Cpoco

public class SomeEntity
{
    public int Id { get; set; }
    [Column(TypeName = "jsonb")]
    public string Customer { get; set; }
}

lub via fluent api

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.Entity<SomeEntity>()
		.Property(b => b.Customer)
		.HasColumnType("jsonb");
}

a następnie

var joes = context.CustomerEntries
	.Where(e => e.Customer.Name == "Joe")
	.ToList();

The provider will recognize the traversal of a JSON document, and translate it to the correspond PostgreSQL JSON traversal operator, producing the following PostgreSQL-specific SQL:

SELECT c.""Id"", c.""Customer""
FROM ""CustomerEntries"" AS c
WHERE c.""Customer""->>'Name' = 'Joe'

1 użytkowników online, w tym zalogowanych: 0, gości: 1