Linq2Db + EF Core 6 + Npgsql 6 + Npgsql.NodaTime = DateTime kind gets lost... Sometimes?!
See original GitHub issueThis is a weird issue which I am unable to reproduce on a smaller example (surprisingly, it seems to work just fine when attempting to create a one-file repro - hence the “Sometimes”).
Sometimes, when using Linq2Db with EF Core 6, Npgsql 6 and Npgsql.NodaTime, but still using the good old DateTime types, the DateTime.Kind gets reset from Utc to Unspecified. Which unfortunately leads to an exception in Npgsql in a simple query like that:
MappingSchema.Default.SetConverter<NodaTime.Instant, DateTime>(timeStamp =>
timeStamp.ToDateTimeUtc());
public class Position
{
// whatever
public DateTime? EndDate {get; set;}
}
var result = await (from pos in _ctx.Positions
where pos.EndDate > DateTime.UtcNow
select pos).ToArrayAsyncLinqToDb();
'System.InvalidCastException: Cannot write DateTime with Kind=Unspecified to PostgreSQL type 'timestamp with time zone', only UTC is supported. Note that it's not possible to mix DateTimes with different Kinds in an array/range. See the Npgsql.EnableLegacyTimestampBehavior AppContext switch to enable legacy behavior.
at Npgsql.Internal.TypeHandlers.DateTimeHandlers.TimestampTzHandler.ValidateAndGetLength(DateTime value, NpgsqlParameter parameter)
at Npgsql.NodaTime.Internal.TimestampTzHandler.Npgsql.Internal.TypeHandling.INpgsqlSimpleTypeHandler<System.DateTime>.ValidateAndGetLength(DateTime value, NpgsqlParameter parameter)
at Npgsql.NodaTime.Internal.TimestampTzHandler.ValidateObjectAndGetLength(Object value, NpgsqlLengthCache& lengthCache, NpgsqlParameter parameter)
at Npgsql.NpgsqlParameter.ValidateAndGetLength()
at Npgsql.NpgsqlParameterCollection.ValidateAndBind(ConnectorTypeMapper typeMapper)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at LinqToDB.Data.DataConnection.ExecuteReaderAsync(CommandBehavior commandBehavior, CancellationToken cancellationToken)
Now again, the weirdest thing is that on the repro it does work, but not on my main project with migrations and tons of stuff, and after experimenting (a lot) I just can’t seem to find the cause!
This bug really made me crazy, and the actual query is a lot more complicated, so I can’t just fallback to EF Core, but on MY context even this simple one fails - and inspecting the actual query parameters - I see that for some reason the DateTime.Kind changed from Utc to Unspecified, and I have no ideas why!
The problem is that from Npgsql 6 they changed the mappings and now enforce the Kind to be Utc, so that’s a deal breaker, and I can’t fallback to the legacy option too anymore.
And yes, I had to mix up NodaTime with DateTime and honestly, I regret it deeply, but I can’t change it at this stage - it’s way too late for that.
Issue Analytics
- State:
- Created 2 years ago
- Comments:18 (4 by maintainers)
Top GitHub Comments
don’t close, we should investigate why it happens, could be a bug somewhere in linq2db
You have to specify
DateTime?
converter also: