linq2db / linq2db.EntityFrameworkCore

Bring power of Linq To DB to Entity Framework Core projects
MIT License
449 stars 39 forks source link

Properties mapping to PostgreSQL Json/JsonB types is not working. #393

Open GlebGQ opened 3 weeks ago

GlebGQ commented 3 weeks ago

I have the following entity:

 public class Message
  {
    public Guid Id { get; set; }
    public string Payload { get; set; }
    public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
  }

with the EF configuration:

public class MessageConfiguration : IEntityTypeConfiguration<Message>
{
    private readonly string _schema;
    private readonly string _table;

    public OutboxEntityConfiguration(string schema, string table)
    {
        _schema = schema;
        _table = table;
    }

    public void Configure(EntityTypeBuilder<Message> builder)
    {
        _ = builder.ToTable(_table, _schema);

        _ = builder.HasKey(x => x.Id);

        _ = builder.Property(x => x.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        _ = builder.Property(x => x.Payload)
            .HasColumnName("payload")
            .HasColumnType("jsonb");

        _ = builder.Property(x => x.Headers)
            .HasColumnType("json")
            .HasColumnName("headers");
    }
}

but when I'm trying to execute the following code:

await _dbContext.Messages
            .ToLinqToDBTable()
            .Merge()
            .Using(entities)
            .OnTargetKey()
            .InsertWhenNotMatched()
            .MergeAsync(cancellationToken);

The exception is thrown:

Error
Exception: Npgsql.PostgresException
Message  : 42804: column "payload" is of type jsonb but expression is of type text

The generated SQL is the following:

DECLARE @value Json -- Object
SET     @value = {[traceparent, 00-d82e97dfd4a6f2f9b5439e35f3300fa2-55f22fb896172514-01]}

MERGE INTO messages "Target"
USING (VALUES ('2edcf165-b97a-4026-89a6-95cc6132532d'::uuid,,'{"jsonProp1":"8421ac39-830e-4251-81d5-619741045408","jsonProp2":0,"jsonProp3":"value3"}',:value) 
) "Source"
(
        "Id",
        "Payload",
        "Headers"
)
ON ("Target".id = "Source"."Id")

WHEN NOT MATCHED THEN
INSERT
(
        id,
        payload,
        headers,
)
VALUES
(
        "Source"."Id",
        "Source"."Payload",
        "Source"."Headers",
)