[Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime] saving CLR DateTime field throws exception
See original GitHub issueHello,
it seems that using of Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime
somehow blocks/corrupts working with CLR DateTime/DateTimeOffset types of properties. When trying to save DateTime
field, an exception is being thrown:
System.InvalidCastException : Can't write CLR type System.DateTime with handler type TimestampHandler
Steps to reproduce
.csproj
references:
<PackageReference Include="Npgsql" Version="4.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.1.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
Code:
public class NpgsqlNodaTimeTests
{
public const string ConnectionString = "connection-string";
[Fact]
public async Task SavingDateTime_ShouldNotThrow()
{
var context = new BlogContext();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var blog = new Blog { Id = 1, Created = DateTime.Now };
context.Blogs.Add(blog);
await context.SaveChangesAsync();
}
}
public class Blog
{
public int Id { get; set; }
public DateTime Created { get; set; }
}
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
=> builder.UseNpgsql(NpgsqlNodaTimeTests.ConnectionString, o => o.UseNodaTime());
protected override void OnModelCreating(ModelBuilder builder)
=> builder.Entity<Blog>().HasKey(p => p.Id);
}
Exception
Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
---- System.InvalidCastException : Can't write CLR type System.DateTime with handler type TimestampHandler
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken) in C:\projects\EFCore.PG\src\EFCore.PG\Storage\Internal\NpgsqlExecutionStrategy.cs:line 72
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at NpgsqlNodaTimeTests.SavingDateTime_ShouldNotThrow() in -CUT--
--- End of stack trace from previous location where exception was thrown ---
----- Inner Stack Trace -----
at lambda_method(Closure , NpgsqlTypeHandler , Object , NpgsqlLengthCache& , NpgsqlParameter )
at Npgsql.TypeHandling.NpgsqlSimpleTypeHandler`1.ValidateObjectAndGetLength(Object value, NpgsqlLengthCache& lengthCache, NpgsqlParameter parameter) in C:\projects\npgsql\src\Npgsql\TypeHandling\NpgsqlSimpleTypeHandler.cs:line 236
at Npgsql.NpgsqlParameter.ValidateAndGetLength() in C:\projects\npgsql\src\Npgsql\NpgsqlParameter.cs:line 553
at Npgsql.NpgsqlCommand.ValidateParameters() in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 793
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1141
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteAsync(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:13 (8 by maintainers)
Top Results From Across the Web
NodaTime.Duration not recognized as primitive type by EF ...
I am not sure what I am missing here - do I need additional (other than .UseNodaTime()) configuration of Npgsql? Package versions: < ......
Read more >NodaTime Type Plugin
Npgsql provides a plugin that allows mapping the NodaTime date/time library; this is the recommended way to interact with PostgreSQL date/time types, rather ......
Read more >Mapping .NET Timestamps to PostgreSQL - Shay Rojansky
Npgsql 6.0 contains some significant changes to how timestamps are ... send a non-UTC DateTime as timestamptz will throw an exception, etc.
Read more >Datetime error with .NET 6 and PostgreSQL - Duong's Blog
While upgrading a project to .NET 6, I ran into an datetime issue with the latest npgsql efcore provider. Today, we will look...
Read more >Untitled
Npgsql exception types WebI get an exception "The field field1 has a type currently unknown to ... NodaTime] saving CLR … ... Cannot...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
First, https://github.com/npgsql/npgsql/pull/3124 was recently merged, which means it will soon be fine to use both NodaTime and BCL date/time types on the same connection etc. (this should happen in the upcoming 5.0 release).
As of today, you can’t natively use NodaTime types - including Duration - and BCL date/time types together; by natively I mean “without a value converter”. If you want to use a value converter and convert from NodaTime to BCL types yourself, it will work (and you don’t need to install the NodaTime plugin), but query translation won’t work - you can’t access properties on value-converted values inside a LINQ query.
Hope that clarifies things.
I have the same issue. We use IdentityFramework with approx. 20 additional entities. Unfortunately, it has must-have properties on User that are DateTimeOffset types. On the other hand, we use NodaTime types due to their advantages in our own entities. Since we derive our context from IdentityDbContext to share the database. It is not the best to have separate DbContexts just to separate identity and other data - not to mention if you have foreign keys.
I normally expected that Noda plugins just “adds” support for these types, not replaces support for DateTime. In my opinion, this should be supported in parallel.
Value converters are not options for us due to missing SQL translation in the current EF Core version (2.2).
What are your opinions?