NpgsqlModelValidator rejects properties mapped via ValueConverter in EF Core 10
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
Direzione di ricerca
Start by reading EF Core 10's ModelValidator.ValidatePropertyMapping and the related relational validation code described in the report; compare their behavior with EF Core 9. Reproduce the failure with the supplied ValueConverter example and check the provider's model validation tests for a suitable regression test. Done means converter-backed properties with a valid provider type mapping pass validation, while genuinely unmapped properties still fail.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
NpgsqlModelValidator rejects properties mapped via ValueConverter (no native type mapping) in EF Core 10
Environment
Microsoft.EntityFrameworkCore:10.0.2Npgsql.EntityFrameworkCore.PostgreSQL:10.0.0- .NET target framework:
net10.0 - PostgreSQL: any 10+
Symptoms
A model that maps a readonly struct (or any non-primitive CLR type) to a primitive database type via ValueConverter<TModel, TProvider> fails to build with:
System.InvalidOperationException: The property 'ItemDefinition.Name' could not be mapped
because it is of type 'LocalizedString', which is not a supported primitive type or a valid entity type.
Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by
using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IConventionTypeBase, IConventionModel, IDiagnosticsLogger`1)
at MUnique.OpenMU.Persistence.EntityFramework.EntityDataContext.OnModelCreating(...)
at ...
The same model builds and works correctly under EF Core 9 (Microsoft.EntityFrameworkCore 9.0.x + Npgsql.EntityFrameworkCore.PostgreSQL 9.0.x).
Root cause
EF Core 10's ModelValidator.ValidatePropertyMapping(IConventionTypeBase, IConventionModel, IDiagnosticsLogger<Validation>) runs:
IConventionProperty conventionProperty = structuralType.GetDeclaredProperties()
.FirstOrDefault(p =>
(!ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())
|| !p.IsImplicitlyCreated())
&& p.FindTypeMapping() == null);
if (conventionProperty != null)
ThrowPropertyNotMappedException(...);
FindTypeMapping() returns null for a property whose CLR type has no native relational mapping and whose mapping is established solely through a ValueConverter registered via OnModelCreating. EF Core 9's relational validator consulted the registered converter before this check; EF Core 10 does not.
Confirmed by decompiling both Microsoft.EntityFrameworkCore.Relational 10.0.0 and Npgsql.EntityFrameworkCore.PostgreSQL 10.0.0 with ILSpy.
Minimal reproduction
// Program.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql;
public readonly struct LocalizedString
{
public string Value { get; }
public LocalizedString(string? value) { Value = value; }
public static implicit operator string(LocalizedString ls) => ls.Value;
}
public class LocalizedStringConverter : ValueConverter<LocalizedString, string>
{
public LocalizedStringConverter() : base(ls => ls.Value ?? "", s => new LocalizedString(s)) { }
}
public class Item
{
public int Id { get; set; }
public LocalizedString Name { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Item> Items => Set<Item>();
protected override void OnConfiguring(DbContextOptionsBuilder o)
=> o.UseNpgsql("Host=localhost;Database=test;Username=postgres;Password=postgres");
protected override void OnModelCreating(ModelBuilder m)
{
m.Entity<Item>(e =>
{
e.Property(p => p.Name).HasConversion(new LocalizedStringConverter());
});
}
}
public class Program
{
public static void Main()
{
using var ctx = new TestContext();
ctx.Database.OpenConnection(); // Triggers model validation
}
}
Expected: ctx.Database.OpenConnection() returns without throwing.
Actual: throws InvalidOperationException: The property 'Item.Name' could not be mapped because it is of type 'LocalizedString'.
The same code runs cleanly under EF Core 9 + Npgsql 9.0.4 (the same ValueConverter<LocalizedString, string> is sufficient to make EF Core 9 happy).
Impact
Many production codebases map readonly struct value objects (translated-text wrappers, currency, units of measure, JSON-shaped DTOs) through ValueConverter. EF Core 10's regression in this area forces users either to:
- mark the type as a complex type via
[ComplexType], which has different semantics and does not always work (verified against EF Core 10.0.2 with a converter-backed property on a complex type — the same exception is raised); - or to fork the provider with a custom
IModelValidatorthat catches the diagnostic (what I am doing locally to unblock OpenMU — seeffuhr91/OpenMU@fix/npgsql-validator-localizedstring).
Neither is a satisfying fix for the long term.
Suggested fix
ModelValidator.ValidatePropertyMapping(IConventionTypeBase, IConventionModel, IDiagnosticsLogger<Validation>) should consult property.GetValueConverter() (and, by extension, the resulting provider-side type mapping) before declaring the property unmapped. The EF Core 9 relational validator effectively did this; the EF Core 10 rewrite dropped the check.
A targeted fix could be:
IConventionProperty conventionProperty = structuralType.GetDeclaredProperties()
.FirstOrDefault(p =>
(!ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())
|| !p.IsImplicitlyCreated())
&& p.FindTypeMapping() == null
&& p.GetValueConverter() == null); // <-- new clause
This restores the EF Core 9 behaviour: properties with a registered ValueConverter are not flagged as "no type mapping", because the converter establishes the mapping to a supported provider type.
Suggested labels
bugarea: model validationseverity: highaffects: 10.0.0
Related
- OpenMU
ffuhr91/OpenMU@fix/npgsql-validator-localizedstring— a workingIModelValidatorsubclass that catches this diagnostic so the game server can boot while the upstream issue is open. - I also plan to file a separate report on the EF Core 10 SQL-generation regression that references a non-existent
ItemDefinitionTempId3column when serializing the OpenMUGameConfigurationaggregate.
- Lingua principale
- C#
- Stelle
- 1.8k
- Fork
- 268
- Merge medio
- 2h 35m
- PR unite (30g)
- 136
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di npgsql/efcore.pg
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSONForse già presa @Ahmed7991 l’ha presa 5 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
npgsql/efcore.pg#4093 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by fieldForse già presa @jeremy-morren l’ha presa 11 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01Forse già presa @Sorbitol l’ha presa 12 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 30/100
I maintainer di solito rispondono entro 1 giorno
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never matchForse già presa @Mr444-dev l’ha presa 7 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
npgsql/efcore.pg#4099 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di npgsql/efcore.pg
Issue simili
-
Issue-Bug Needs-Triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
I maintainer di solito rispondono entro 1 giorno
-
area/access-management Frontend onboarding candidate :handshake:
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
Altinn/altinn-auth#4941 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
aws/aws-sdk-net#4586 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
Kryptos-FR/MarkView.Avalonia#269 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno