Skip to content

TargetInvocationException with non-instantiable array over value-converted elements #3050

Description

@JustArchi

Minimum working repro extracted from real application:

[Table("listed_users")]
public sealed class ListedUser {
	[Column]
	[Key]
	public ulong SteamID { get; set; }
}

public sealed class MyContext : DbContext {
	public DbSet<ListedUser> ListedUsers => Set<ListedUser>();

	public MyContext(DbContextOptions<MyContext> options) : base(options) { }
}

Dictionary<Task<bool>, ulong> tasks = new();

// Throws exception
await context.ListedUsers.Where(user => !tasks.Values.Contains(user.SteamID)).ToListAsync().ConfigureAwait(false);

// This workaround makes it work however
ICollection<ulong> workaround = tasks.Values;

await context.ListedUsers.Where(user => !workaround.Contains(user.SteamID)).ToListAsync().ConfigureAwait(false);

This worked fine in EF Core 7 (.NET 7). After update to 8.0.0, it now throws with below details:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.ArgumentException: Expression of type 'System.Threading.Tasks.Task`1[System.Boolean]' cannot be used for parameter of type 'System.UInt64' (Parameter 'arg0')
   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
   at System.Linq.Expressions.Expression.Invoke(Expression expression, Expression arg0)
   at System.Linq.Expressions.Expression.Invoke(Expression expression, IEnumerable`1 arguments)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3.ArrayConversionExpression[TInput,TOutput,TConcreteOutput](LambdaExpression elementConversionExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3..ctor(ValueConverter elementConverter)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3.CreateParameters(String storeType, RelationalTypeMapping elementMapping)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(String storeType, RelationalTypeMapping elementTypeMapping)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(RelationalTypeMapping elementTypeMapping)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlTypeMappingSource.FindCollectionMapping(RelationalTypeMappingInfo info, Type modelType, Type providerType, CoreTypeMapping elementMapping)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.<>c.<FindMappingWithConversion>b__8_0(ValueTuple`4 k, RelationalTypeMappingSource self)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMappingWithConversion(RelationalTypeMappingInfo mappingInfo, Type providerClrType, ValueConverter customConverter)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(Type type, IModel model, CoreTypeMapping elementMapping)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateContains(ShapedQueryExpression source, Expression item)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at ArchiSteamFarmBackend.Program.Init(String[] args) in /home/archi/git/JustArchiNET/ArchiSteamFarmBackend/ArchiSteamFarmBackend/Program.cs:line 279
   at ArchiSteamFarmBackend.Program.Init(String[] args) in /home/archi/git/JustArchiNET/ArchiSteamFarmBackend/ArchiSteamFarmBackend/Program.cs:line 280

For reference, I checked latest upcoming patch version in addition to 8.0.0: 8.0.1-ci.20240105T091620.

The workaround I found suggests this should be easy to fix, although I'm not an expert 🙂

/cc @roji

Activity

  1. changed the title [-]Query error after update to .NET 8[/-] [+]`TargetInvocationException` error during query after update to .NET 8[/+] on Jan 5, 2024
  2. dagophil commented on Feb 15, 2024

    @dagophil

    I am getting a similar exception after the update to .NET 8. However, I am not sure if it is for the same root cause. My entites use strongly typed keys, e.g., there is a struct EntityId<T> which has a value converter to long.

    The query is similar to yours, e.g., I try to query by some collection and there is a value conversion involved:

    public class Book
    {
        public EntityId<Book> Id { get; set; }
        public string Title { get; set; } = "";
        public EntityId<Author>? AuthorId { get; set; }
    }
    
    ICollection<EntityId<Author>> authorIds = new List<EntityId<Author>> { new(1) };
    var books = await context.Set<Book>()
        .Where(o => o.AuthorId != null && authorIds.Contains(o.AuthorId.Value))
        .ToListAsync();

    In .NET 7 with Npgsql.EntityFrameworkCore.PostgreSQL 7.0.11 and Microsoft.AspNetCore.Identity.EntityFrameworkCore 7.0.16, everything works fine.
    In .NET 8 with Npgsql.EntityFrameworkCore.PostgreSQL 8.0.0 and Microsoft.AspNetCore.Identity.EntityFrameworkCore 8.0.2, the following exception is thrown:

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.ArgumentException: Expression of type 'MyApp.EntityId`1[MyApp.Author]' cannot be used for parameter of type 'System.Nullable`1[MyApp.EntityId`1[MyApp.Author]]' (Parameter 'arg0')
       at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
       at System.Linq.Expressions.Expression.Invoke(Expression expression, Expression arg0)
       at System.Linq.Expressions.Expression.Invoke(Expression expression, IEnumerable`1 arguments)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3.ArrayConversionExpression[TInput,TOutput,TConcreteOutput](LambdaExpression elementConversionExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3..ctor(ValueConverter elementConverter)
       at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
       at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)   at System.Activator.CreateInstance(Type type, Object[] args)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3.CreateParameters(String storeType, RelationalTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(String storeType, RelationalTypeMapping elementTypeMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(RelationalTypeMapping elementTypeMapping)
       at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
       at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)   at System.Activator.CreateInstance(Type type, Object[] args)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlTypeMappingSource.FindCollectionMapping(RelationalTypeMappingInfo info, Type modelType, Type providerType, CoreTypeMapping elementMapping)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.<>c.<FindMappingWithConversion>b__8_0(ValueTuple`4 k, RelationalTypeMappingSource self)
       at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMappingWithConversion(RelationalTypeMappingInfo mappingInfo, Type providerClrType, ValueConverter customConverter)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(Type type, IModel model, CoreTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateContains(ShapedQueryExpression source, Expression item)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
       at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
       at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
       at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
       at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
       at Program.<Main>$(String[] args) in C:\Code\test_postgres_exception\MyApp\Program.cs:line 23
       at Program.<Main>(String[] args)
    

    Here is a small example that reproduces the exception:
    postgres_exception.zip

  3. roji commented on Feb 15, 2024

    @roji
    Member

    Thanks for the reports and the repro - I'll try to find some time in the coming week or two to take a look.

  4. dagophil commented on Feb 15, 2024

    @dagophil

    Thank you :)

  5. dagophil commented on Mar 4, 2024

    @dagophil

    @roji I think I found some problematic code in the the NpgsqlArrayConverter that could be related to our problem. See line 142.

    I used the code from the first comment, e.g., a local variable Dictionary<Task<bool>, ulong> tasks = new(); that is used in the query with .Where(o => !tasks.Values.Contains(o.Id)). This caused the NpgsqlArrayConverter to be called with

    • TInput: Dictionary<Task, ulong>.ValueCollection
    • TOutput: Decimal[]
    • TConcreteOutput: Decimal[]

    Say the input type is an IEnumerable<T>. Then the code tries to construct a type IList<T> using the following code:

    var iListType = typeof(IList<>).MakeGenericType(typeof(TInput).GetGenericArguments()[0]);

    This makes the assumption that the concrete type TInput uses its first generic argument as type for IEnumerable<>. This is not always true. For example, for Dictionary<TKey, TValue>.ValueCollection, the first argument is TKey, but it uses the second argument TValue for IEnumerable<TValue>.
    Maybe one needs something like this:

    var valueType = typeof(TInput).GetInterfaces()
        .First(o => o.IsGenericType && o.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        .GetGenericArguments()[0];
    var iListType = typeof(IList<>).MakeGenericType(valueType);

    After making these changes locally, the code continues instead of throwing above exception. However, it calls the converter a second time:

    • TInput: Decimal[]
    • TOutput: Dictionary<Task, ulong>.ValueCollection
    • TConcreteOutput: Dictionary<Task, ulong>.ValueCollection

    Then, in line 165-169, the code fails with an exception because it cannot find a suitable Dictionary<TKey, TValue>.ValueCollection constructor. I have no idea how to continue from here.

    I wonder why a converter is built here at all. After all, the code only needs to write the values from the enumerable into the query. It should not need to perform any back- and forth-conversion of the underlying collection.

  6. dagophil commented on Mar 4, 2024

    @dagophil

    @roji Another possibly problematic code is line 85-87.

    The comment says:

    // elementConversionExpression is always over non-nullable value types.

    Is that so? In first comment, I used a model with a nullable property, e.g., public EntityId<Author>? AuthorId { get; set; }. The according value converter looks like this:

    public class NullableEntityIdToLongConverter<T> : ValueConverter<EntityId<T>?, long?>
    {
        public NullableEntityIdToLongConverter()
            : base(
                o => o.HasValue ? o.Value.Value : null,
                o => o.HasValue ? new EntityId<T>(o.Value) : null)
        {
        }
    }

    I think nullable value types are allowed in converters, arent they? Maybe the NpgsqlArrayConverter needs to update the elementConversionExpression accordingly.

  7. self-assigned this
    on Mar 4, 2024
  8. added this to the 8.0.3 milestone on Mar 4, 2024
  9. roji commented on Mar 4, 2024

    @roji
    Member

    @dagophil thanks for the added detail - I still have too many other things going on, but this definitely will be in my list of things to look into for 8.0.3. Sorry for the delay and thanks for your patience...

  10. dagophil commented on Mar 4, 2024

    @dagophil

    @roji No problem, thank you for looking into this :)

  11. roji commented on Mar 22, 2024

    @roji
    Member

    @dagophil I took a first look here - I could indeed repro the problem (see below for a minimal distilled code sample).

    My first question where would be why you have a NullableEntityIdToLongConverter; simply using EntityIdToLongConverter makes the error go away in 8.0, and should work fine (EF handles nulls around value converters, so that converters don't typically need to worry about these).

    Note that I'm not saying there's no bug in 8.0 - this code did use to work in 7.0 - but I'm curious whether there's a specific reason you have NullableEntityIdToLongConverter.

    Repro
    await using var context = new BlogContext();
    await context.Database.EnsureDeletedAsync();
    await context.Database.EnsureCreatedAsync();
    
    ICollection<EntityId> authorIds = new List<EntityId> { new(1), new(2) };
    var books = await context.Books.Where(o => authorIds.Contains(o.AuthorId.Value)).ToListAsync();
    
    public class BlogContext : DbContext
    {
        public DbSet<Book> Books { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
                .UseNpgsql("Host=localhost;Username=test;Password=test")
                .LogTo(Console.WriteLine, LogLevel.Information)
                .EnableSensitiveDataLogging();
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var authorBuilder = modelBuilder.Entity<Author>();
            authorBuilder.Property(o => o.Id).HasConversion<EntityIdToLongConverter>().ValueGeneratedOnAdd();
    
            var bookBuilder = modelBuilder.Entity<Book>();
            // Changing the following to EntityIdToLongConverter<Author> makes the error go away
            bookBuilder.Property(o => o.AuthorId).HasConversion<NullableEntityIdToLongConverter>();
        }
    
        public class EntityIdToLongConverter() : ValueConverter<EntityId, long>(
            o => o.Value,
            o => new EntityId(o));
    
        public class NullableEntityIdToLongConverter() : ValueConverter<EntityId?, long?>(
            o => o.HasValue ? o.Value.Value : null,
            o => o.HasValue ? new EntityId(o.Value) : null);
    }
    
    public class Book
    {
        public int Id { get; set; }
        public string Title { get; set; } = "";
        public EntityId? AuthorId { get; set; }
    }
    
    public class Author
    {
        public EntityId Id { get; set; }
        public string Name { get; set; } = "";
    }
    
    public record struct EntityId(long Value);
  12. dagophil commented on Mar 23, 2024

    @dagophil

    @roji

    My first question where would be why you have a NullableEntityIdToLongConverter; simply using EntityIdToLongConverter makes the error go away in 8.0, and should work fine (EF handles nulls around value converters, so that converters don't typically need to worry about these).

    Well, I did not know that. I guess I overlooked the relevant note in the value converter documentation, but now I found it. I threw away those unnecessary nullable-converters and now everything works as expected. .NET 8 here I come :)

    Thank you for your advice!

    Alas, I dont think this helps the original poster with their problem, because there are no custom value converters involved.

  13. JustArchi commented on Mar 27, 2024

    @JustArchi
    Author

    Yeah, the original issue still stands and I don't believe there is any user error there, not only because it worked fine before, but also because I don't see anything to change or improve in that code in order to solve the exception thrown 🙂.

  14. modified the milestones: 8.0.4, 8.0.5 on May 11, 2024
  15. 6 remaining items

  16. modified the milestones: 8.0.11, 8.0.12 on Nov 18, 2024
  17. ezhevita commented on Dec 16, 2024

    @ezhevita

    A similar issue, but this one started throwing the exception only from 9.0.0 onwards:

    Dictionary<ulong, EFlags> dictionary = new();
    // throws
    var existingAccounts = await _dbContext.Accounts.Where(x => dictionary.Keys.Contains(x.ExternalId)).ToListAsync();
    
    ICollection<ulong> workaround = dictionary.Keys;
    // doesn't throw
    var existingAccounts = await _dbContext.Accounts.Where(x => workaround.Contains(x.ExternalId)).ToListAsync();

    The exception:

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.ArgumentNullException: Value cannot be null. (Parameter 'constructor')
       at System.ArgumentNullException.Throw(String paramName)
       at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
       at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments)
       at System.Linq.Expressions.Expression.New(ConstructorInfo constructor)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3.ArrayConversionExpression[TInput,TOutput,TConcreteOutput](LambdaExpression elementConversionExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3..ctor(ValueConverter elementConverter)
       at InvokeStub_NpgsqlArrayConverter`3..ctor(Object, Span`1)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
       at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
       at System.Activator.CreateInstance(Type type, Object[] args)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3.CreateParameters(String storeType, RelationalTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(String storeType, RelationalTypeMapping elementTypeMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(RelationalTypeMapping elementTypeMapping)
       at InvokeStub_NpgsqlArrayTypeMapping`3..ctor(Object, Span`1)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
       at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
       at System.Activator.CreateInstance(Type type, Object[] args)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlTypeMappingSource.FindCollectionMapping(RelationalTypeMappingInfo info, Type modelType, Type providerType, CoreTypeMapping elementMapping)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.<>c.<FindMappingWithConversion>b__8_0(ValueTuple`4 k, RelationalTypeMappingSource self)
       at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMappingWithConversion(RelationalTypeMappingInfo mappingInfo, Type providerClrType, ValueConverter customConverter)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(Type type, IModel model, CoreTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateContains(ShapedQueryExpression source, Expression item)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.<VisitMethodCall>g__TranslateAsSubquery|33_0(Expression expression, <>c__DisplayClass33_0&)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
       at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
       at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
       at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
       at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
       at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
       at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
       at // application code
    
  18. JustArchi commented on Sep 19, 2025

    @JustArchi
    Author

    FYI as of .NET 10 rc1, the issue is still relevant, although the exact exception (stacktrace) changed a little.

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
     ---> System.ArgumentException: Property 'Int32 Count' is not defined for type 'System.Collections.Generic.Dictionary`2+ValueCollection[System.Threading.Tasks.Task`1[System.Boolean],System.UInt64]' (Parameter 'property')
       at System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3.ArrayConversionExpression[TInput,TOutput,TConcreteOutput](LambdaExpression elementConversionExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion.NpgsqlArrayConverter`3..ctor(ValueConverter elementConverter)
       at InvokeStub_NpgsqlArrayConverter`3..ctor(Object, Span`1)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3.CreateParameters(String storeType, RelationalTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(String storeType, RelationalTypeMapping elementTypeMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping`3..ctor(RelationalTypeMapping elementTypeMapping)
       at InvokeStub_NpgsqlArrayTypeMapping`3..ctor(Object, Span`1)
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       --- End of inner exception stack trace ---
       at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlTypeMappingSource.FindCollectionMapping(RelationalTypeMappingInfo info, Type modelType, Type providerType, CoreTypeMapping elementMapping)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.<>c.<FindMappingWithConversion>b__8_0(ValueTuple`4 k, RelationalTypeMappingSource self)
       at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMappingWithConversion(RelationalTypeMappingInfo mappingInfo, Type providerClrType, ValueConverter customConverter)
       at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(Type type, IModel model, CoreTypeMapping elementMapping)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.NpgsqlSqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateContains(ShapedQueryExpression source, Expression item)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.<VisitMethodCall>g__TranslateAsSubquery|31_0(Expression expression, <>c__DisplayClass31_0&)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean applyDefaultTypeMapping)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
       at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
       at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
       at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
       at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
       at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
       at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
       at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
       at ArchiSteamFarmBackend.Program.Init() in /home/archi/git/JustArchiNET/ArchiSteamFarmBackend/ArchiSteamFarmBackend/Program.cs:line 135
       at ArchiSteamFarmBackend.Program.Init() in /home/archi/git/JustArchiNET/ArchiSteamFarmBackend/ArchiSteamFarmBackend/Program.cs:line 265
    
  19. roji commented on Oct 2, 2025

    @roji
    Member

    @ezhevita @JustArchi and others, are you also trying to use a nullable value-type value converter (see above comment), and can make the issue go away by simply switching to a non-nullable one?

    Otherwise, you may be seeing a different issue which happens to have the same exception message. In that case, please open a new issue with a full minimal repro (as I'm only seeing vague fragments), and link to it from here.

  20. JustArchi commented on Oct 4, 2025

    @JustArchi
    Author

    @roji I'm not using any converter, in the original post you can find a repro that works on .NET 8, 9 as well as 10 - and the problem that this task considers.

    The one reported by dagophil is actually entirely different issue that should have its own report if needed 🙂

  21. roji commented on Oct 5, 2025

    @roji
    Member

    I'm not using any converter, in the original post you can find a repro [...]

    You actually are. Like other relational databases, PostgreSQL doesn't support unsigned numeric types, so when you use ulong, you're implicitly using a value converter (the database type is numeric(20,0). If you switch from ulong to long your repro works (and uses a bigint in the database) - that's what I'd recommended doing in general, unless you have a very specific need to use the unsigned type (i.e. need to store values beyond long.MaxValue - which is quite rare).

    In any case, I've submitted #3629 to fix this for the upcoming 10 release.

    Minimal repro
    await using var context = new BlogContext();
    await context.Database.EnsureDeletedAsync();
    await context.Database.EnsureCreatedAsync();
    
    Dictionary<Task<bool>, ulong> tasks = new();
    
    // Throws exception
    await context.Users.Where(user => !tasks.Values.Contains(user.Id)).ToListAsync().ConfigureAwait(false);
    
    // This workaround makes it work however
    // ICollection<ulong> workaround = tasks.Values;
    // await context.ListedUsers.Where(user => !workaround.Contains(user.SteamID)).ToListAsync().ConfigureAwait(false);
    
    public class BlogContext : DbContext
    {
        public DbSet<User> Users => Set<User>();
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
                .UseNpgsql("Host=localhost;Username=test;Password=test")
                .LogTo(Console.WriteLine, LogLevel.Information)
                .EnableSensitiveDataLogging();
    }
    
    public sealed class User
    {
    	public ulong Id { get; set; }
    }
  22. modified the milestones: 8.0.12, 10.0.0 on Oct 5, 2025
  23. added theissue type on Oct 5, 2025
  24. changed the title [-]`TargetInvocationException` error during query after update to .NET 8[/-] [+]TargetInvocationException with non-instantiable array over value-converted elements[/+] on Oct 5, 2025
  25. added a commit that references this issue on Oct 5, 2025
    e2b3d72
  26. JustArchi commented on Oct 5, 2025

    @JustArchi
    Author

    Thanks @roji - indeed, I'm storing values beyond long.MaxValue and need ulong for this purpose. I'm aware postgresql is using numeric(20, 0) under the hood for that, I wasn't aware there is value converter behind that, but it makes total sense as there's no native type like you said. Much appreciated for the fix! 🥳

  27. JustArchi commented on Nov 22, 2025

    @JustArchi
    Author

    FYI I can confirm that this issue is no longer reproducible with 10.0, thanks again! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions