Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullReferenceException for a custom ValueConverter in EF Core 9 RC 1. #34760

Open
maliming opened this issue Sep 26, 2024 · 0 comments
Open

NullReferenceException for a custom ValueConverter in EF Core 9 RC 1. #34760

maliming opened this issue Sep 26, 2024 · 0 comments
Assignees

Comments

@maliming
Copy link

maliming commented Sep 26, 2024

The csproj and code to reproduce:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0-rc.1.24451.1">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        <PrivateAssets>all</PrivateAssets>
      </PackageReference>
      <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0-rc.1.24451.1" />
    </ItemGroup>

</Project>
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

var db = new BookContext();

await db.Books.AddAsync( new Book()
{
    CreationDate = DateTime.Now
});

await db.SaveChangesAsync();

var result =  await db.Books
    .GroupBy(t => t.Id)
    .Select(g => new
    {
        Day = g.Min(t => t.CreationDate)
    })
    .ToListAsync();

public class BookContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    public string DbPath { get; }

    public BookContext()
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);
        DbPath = Path.Join(path, "book.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Book>().Property(e => e.CreationDate).HasConversion(new MyDateTimeValueConverter(new MyDatetimeConverter()));
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite($"Data Source={DbPath}", builder => builder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)).EnableDetailedErrors();
}

public class MyDateTimeValueConverter : ValueConverter<DateTime, DateTime>
{
    public MyDateTimeValueConverter(MyDatetimeConverter myDatetimeConverter, ConverterMappingHints? mappingHints = null)
        : base(
            x => myDatetimeConverter.Normalize(x),
            x => myDatetimeConverter.Normalize(x),
            mappingHints)
    {
    }
}

public class Book
{
    public Guid Id { get; set; }

    public virtual DateTime CreationDate { get;  set; }
}


public class MyDatetimeConverter
{
    public virtual DateTime Normalize(DateTime dateTime)
    {
        return dateTime.Date;
    }
}
Unhandled exception. System.InvalidOperationException: An error occurred while reading a database value. The expected type was 'System.Nullable`1[System.DateTime]' but the actual value was null.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at lambda_method34(Closure, QueryContext, DbDataReader, ResultContext, SplitQueryResultCoordinator)
   --- End of inner exception stack trace ---
   at lambda_method34(Closure, QueryContext, DbDataReader, ResultContext, SplitQueryResultCoordinator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in ConsoleApp\ConsoleApp\Program.cs:line 13
   at Program.<Main>(String[] args)

It works if I create the MyDatetimeConverter() object in the expression parameter.
And the all code works in EF Core 8.0.

public class MyDateTimeValueConverter : ValueConverter<DateTime, DateTime>
{
    public MyDateTimeValueConverter(MyDatetimeConverter myDatetimeConverter, ConverterMappingHints? mappingHints = null)
        : base(
            x => new MyDatetimeConverter().Normalize(x),
            x => new MyDatetimeConverter().Normalize(x),
            mappingHints)
    {
    }
}
maliming added a commit to abpframework/abp that referenced this issue Sep 26, 2024
@maumar maumar self-assigned this Sep 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants