question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime] saving CLR DateTime field throws exception

See original GitHub issue

Hello, 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:closed
  • Created 5 years ago
  • Reactions:5
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
rojicommented, Sep 18, 2020

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.

2reactions
krisztiankocsiscommented, May 6, 2019

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?

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found