NpgsqlModelValidator rejects properties mapped via ValueConverter in EF Core 10
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 48/100
Rechercherichtung
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.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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.
- Vorherrschende Sprache
- C#
- Sterne
- 1.8k
- Forks
- 268
- Ø Merge
- 2 Std. 35 Min.
- Gemergte PRs (30 T.)
- 136
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus npgsql/efcore.pg
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
Maintainer antworten meist innerhalb von 1 Tag
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSONEvtl. vergeben @Ahmed7991 hat das vor 5 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
npgsql/efcore.pg#4093 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by fieldEvtl. vergeben @jeremy-morren hat das vor 11 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
Maintainer antworten meist innerhalb von 1 Tag
-
Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01Evtl. vergeben @Sorbitol hat das vor 12 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 30/100
Maintainer antworten meist innerhalb von 1 Tag
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never matchEvtl. vergeben @Mr444-dev hat das vor 7 Tagen übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 45/100
npgsql/efcore.pg#4099 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in npgsql/efcore.pg
Ähnliche Issues
-
Issue-Bug Needs-Triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 2 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
Maintainer antworten meist innerhalb von 1 Tag
-
area/access-management Frontend onboarding candidate :handshake:
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
Altinn/altinn-auth#4941 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
aws/aws-sdk-net#4586 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
Kryptos-FR/MarkView.Avalonia#269 · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag