Skip to content

EF Core 7 System.ArgumentNullException: Value cannot be null. (Parameter 'second') #32881

@KeterSCP

Description

@KeterSCP

This is essentially same as #31717, but that issue was closed as no repro code was provided.

Steps to reproduce

  1. Create console app with following .csproj:
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.11" />
    </ItemGroup>

</Project>
  1. In the Program.cs paste following snippet, and fill the ConnectionString value:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

using var context = new TestContext();

var m = new MyModel
{
    Id = 1,
    Enums = new List<MyEnum> { MyEnum.Value1, MyEnum.Value2 }
};

context.MyModels.Add(m);
context.SaveChanges();

public sealed class TestContext : DbContext
{
    private const string ConnectionString = "";

    public DbSet<MyModel> MyModels { get; set; }

    public TestContext()
    {
        Database.EnsureCreated();
        Database.Migrate();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseNpgsql(ConnectionString);

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyModel>()
            .Property(m => m.Enums)
            .HasColumnType("jsonb")
            .IsRequired()
            .HasDefaultValueSql("'[]'")
            .HasConversion(new EnumCollectionJsonValueConverter<MyEnum>())
            .Metadata.SetValueComparer(new CollectionValueComparer<MyEnum>());
    }
}

public class MyModel
{
    public int Id { get; set; }
    public List<MyEnum> Enums { get; set; }
}

public enum MyEnum
{
    Value1,
    Value2
}

public class EnumCollectionJsonValueConverter<T> : ValueConverter<List<T>, string> where T : struct, Enum
{
    public EnumCollectionJsonValueConverter() : base(
        v => Serialize(v),
        v => Deserialize(v))
    {
    }

    private static string Serialize(List<T> value)
    {
        return JsonSerializer.Serialize(value);
    }

    private static List<T> Deserialize(string valueJson)
    {
        return JsonSerializer.Deserialize<List<T>>(valueJson);
    }
}

public class CollectionValueComparer<T> : ValueComparer<List<T>>
{
    public CollectionValueComparer() : base((c1, c2) => c1.SequenceEqual(c2),
        c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => c.ToList())
    {
    }
}

Include stack traces

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'second')
   at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
   at System.Linq.Enumerable.SequenceEqual[TSource](IEnumerable`1 first, IEnumerable`1 second, IEqualityComparer`1 comparer)
   at lambda_method13(Closure, IUpdateEntry)
   at lambda_method12(Closure, InternalEntityEntry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.OriginalValues..ctor(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.EnsureOriginalValues()
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntrySubscriber.SnapshotAndSubscribe(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey, Nullable`1 fallbackState)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.SetEntityState(InternalEntityEntry entry, EntityState entityState)
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Add(TEntity entity)
   at Program.<Main>$(String[] args) in C:\demo\Program.cs:line 18

Include provider and version information

EF Core version: 7.0.11
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: .NET 7.0
Operating system: Windows 11
IDE: JetBrains Rider 2023.3.1

Additional info

  • There is no exception if I remove .HasDefaultValueSql("'[]'")
  • There is no exception on .NET 8 and Npgsql.EntityFrameworkCore.PostgreSQL 8.0.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions