Querying enum properties inside JSONB columns fails when using JsonStringEnumConverter
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
Línea de trabajo
Start by running the provided reproduction against PostgreSQL, then read the provider's JSONB query translation and related tests. Trace how the enum property's configured JSON converter affects server-side comparisons; done means the Where query compares the stored string value without an integer cast and the relevant tests pass.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Description
When a JSONB column contains a property typed as a C# enum, and JsonStringEnumConverter is configured via ConfigureJsonOptions, any server-side query that references the enum property fails with:
Npgsql.PostgresException: 22P02: invalid input syntax for type integer: "Good"
Npgsql generates SQL that casts the extracted JSON value to integer (the enum's backing type) rather than comparing it as text, even though JsonStringEnumConverter is configured and the JSON stores the enum as its string name.
Materializing the full entity via ToListAsync() works fine — the issue is specifically with server-side evaluation of the enum property (e.g. in Where, GroupBy, OrderBy, etc.).
Steps to Reproduce
Minimal reproduction using dotnet run (requires .NET 10+, PostgreSQL):
#:package [email protected]
#:package [email protected]
#:property PublishAot=false
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.EntityFrameworkCore;
var dbContext = new DemoContext(
"Host=localhost;Database=repro_db;Username=postgres;Password=postgres"
);
dbContext.Database.ExecuteSql(
$$"""
drop table if exists parents;
create table parents
(
id integer not null,
data jsonb not null
);
insert into parents (id, data) values
(1, '{"Status": "Good"}'),
(2, '{"Status": "Good"}'),
(3, '{"Status": "Bad"}'),
(4, '{"Status": "Good"}');
"""
);
// This works — client-side deserialization handles string enums correctly
var resultsThatWork = await dbContext.Parents.ToListAsync();
foreach (var result in resultsThatWork)
{
Console.WriteLine(result);
}
// This fails — server-side evaluation casts "Good" to integer
var goodResults = await dbContext.Parents
.Where(x => x.Data.Status == Status.Good)
.ToListAsync();
foreach (var result in goodResults)
{
Console.WriteLine(result);
}
class DemoContext(string connectionString) : DbContext()
{
public DbSet<Parent> Parents => Set<Parent>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>(entity =>
{
entity.Property(x => x.Data).HasColumnType("jsonb");
});
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseNpgsql(
connectionString: connectionString,
optionsBuilder =>
{
optionsBuilder.ConfigureDataSource(dataSourceBuilder =>
{
dataSourceBuilder
.ConfigureJsonOptions(
new JsonSerializerOptions
{
Converters = { new JsonStringEnumConverter() },
}
)
.EnableDynamicJson();
});
}
)
.UseSnakeCaseNamingConvention();
}
}
class Parent
{
public required long Id { get; set; }
public required ThisIsJson Data { get; set; }
}
class ThisIsJson
{
public required Status Status { get; set; }
}
enum Status
{
Good,
Bad,
}
Expected Behavior
The Where clause should generate SQL that compares the extracted JSON value as text, e.g.:
SELECT ... FROM parents AS p WHERE p.data->>'Status' = 'Good'
Actual Behavior
The generated SQL casts the extracted value to integer, causing PostgreSQL to fail:
Npgsql.PostgresException (0x80004005): 22P02: invalid input syntax for type integer: "Good"
Environment
- Npgsql.EntityFrameworkCore.PostgreSQL: 10.0.0
- .NET: 10
- PostgreSQL: 17.5
- Lenguaje dominante
- C#
- Estrellas
- 1.8k
- Forks
- 268
- Merge medio
- 2 h 35 min
- PR fusionados (30 d)
- 136
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de npgsql/efcore.pg
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSONPosiblemente ocupada @Ahmed7991 la tomó hace 5 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
npgsql/efcore.pg#4093 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by fieldPosiblemente ocupada @jeremy-morren la tomó hace 11 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01Posiblemente ocupada @Sorbitol la tomó hace 12 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 30/100
Los mantenedores suelen responder en 1 día
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never matchPosiblemente ocupada @Mr444-dev la tomó hace 7 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
npgsql/efcore.pg#4099 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de npgsql/efcore.pg
Issues similares
-
Issue-Bug Needs-Triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
Los mantenedores suelen responder en 1 día
-
area/access-management Frontend onboarding candidate :handshake:
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Altinn/altinn-auth#4941 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
aws/aws-sdk-net#4586 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Kryptos-FR/MarkView.Avalonia#269 · 1 reacción ·
Los mantenedores suelen responder en 1 día