efcore.pg: Can't map user-defined range with subtype StoreType when the subtype type is plugin-provided
I’ve attempted to use the new custom range type support with LocalTime (from NodaTime).
So I’ve set it up with:
services.AddDbContext<MainContext>(options =>
options.UseNpgsql(
Configuration.GetConnectionString("MainContext"),
opts =>
{
opts.UseNodaTime();
opts.MapRange<LocalTime>("timerange");
}));
and:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ForNpgsqlHasRange("timerange", "time");
// ...
}
Then in one of my model classes I’ve put:
public NpgsqlRange<LocalTime> Period { get; set; }
Then I ran:
dotnet ef migrations add Initial
and I get:
System.TypeLoadException: Could not load type 'Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlRangeTypeMapping`1' from assembly 'Npgsql.EntityFrameworkCore.PostgreSQL, Version=2.2.0.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7'.
at Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime.NodaTimePlugin..ctor()
at Microsoft.EntityFrameworkCore.NodaTimeDbContextOptionsExtensions.UseNodaTime(NpgsqlDbContextOptionsBuilder optionsBuilder) in /home/roji/projects/EFCore.PG/src/EFCore.PG.NodaTime/NodaTimeDbContextOptionsExtensions.cs:line 20
at Server.Startup.<>c.<ConfigureServices>b__4_2(NpgsqlDbContextOptionsBuilder opts)
These are the versions I’m using:
<PackageReference Include="NodaTime" Version="2.3.0" />
<PackageReference Include="Npgsql" Version="4.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0-preview1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="2.1.1" />
What am I doing wrong?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 15 (10 by maintainers)
Commits related to this issue
- Fix user-defined range mappings We used to eagerly create mappings for user-defined ranges in the constructor of NpgsqlTypeMappingSource. This was too early, and did not have access to mappings comin... — committed to roji/efcore.pg by roji 6 years ago
- Fix user-defined range mappings We used to eagerly create mappings for user-defined ranges in the constructor of NpgsqlTypeMappingSource. This was too early, and did not have access to mappings comin... — committed to npgsql/efcore.pg by roji 6 years ago
@austindrenski OK, I took a look and your analysis seems correct… The user-defined range mapping setup process involves looking at NpgsqlTypeMappingSource’s
ClrTypeMappingdictionary, but that dictionary only includes the built-in mappings, and not the plugins.I think the right way would be to move the user-defined range logic out of the constructor and into
FindMapping(), probably by adding an additionalFindUserDefinedRangeMapping()which gets called, just likeFindArrayMapping(). LikeFindArrayMapping(), if a mapping is instantiated, we can update NpgsqlTypeMappingSource’sClrTypeMappingandStoreTypeMappingdictionaries so that the next lookup simply finds it viaFindExistingMapping(). Also, when looking for the subtype we definitely should not look atClrTypeMapping, but rather recursively callFindMapping()which would include the plugins (again, exactly likeFindArrayMapping()already does).Are you interested in fixing this? If not I can probably do this quite quickly.
@Jefffrey Yes, that’s the exception I referenced above.
@austindrenski I run a
dotnet clean && dotnet restoreyes, and nothing changed.I think you can reproduce the issue by creating a new dotnet project and just define a model with a range for
LocalTimefollowing the first post.