Skip to content

Exception when doing a Contains query against an enum field based on byte #1189

@redoz

Description

@redoz

We just upgraded to EFCore 3.1 which surfaced this issue.

Minimal reproduction:

Repro.csproj:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.0" />
  </ItemGroup>

</Project>

Program.cs

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace Repro
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await using var dbContext = new MyContext();

            SomeEnum[] possibleValues = { SomeEnum.One, SomeEnum.Three };
            var result = await dbContext.My.Where(e => possibleValues.Contains(e.SomeByteValue)).ToListAsync();
        }
    }

    public enum SomeEnum : byte
    {
        One = 1,
        Two = 2,
        Three = 3
    }

    public class MyEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int TheKey { get; set; }
        public SomeEnum SomeByteValue { get; set; }
    }

    public class MyContext : DbContext
    {
        public DbSet<MyEntity> My { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseNpgsql(@"Server=.");
        }
    }
}

This line:

var result = await dbContext.My.Where(e => possibleValues.Contains(e.SomeByteValue)).ToListAsync();

throws the following exception:

System.InvalidCastException: 'Unable to cast object of type 'Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlByteArrayTypeMapping' to type 'Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayTypeMapping'.'

Stacktrace:

This exception was originally thrown at this call stack:
	Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlExpressionFactory.ApplyTypeMappingOnArrayAnyAll(Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal.ArrayAnyAllExpression)
	Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlExpressionFactory.ApplyTypeMapping(Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression, Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapping)
	Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.ApplyDefaultTypeMapping(Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression)
	Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlExpressionFactory.ArrayAnyAll(Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression, Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression, Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal.ArrayComparisonType, string)
	Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal.NpgsqlArrayMethodTranslator.Translate(Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression, System.Reflection.MethodInfo, System.Collections.Generic.IReadOnlyList<Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression>)
	Microsoft.EntityFrameworkCore.Query.RelationalMethodCallTranslatorProvider.Translate.AnonymousMethod__1(Microsoft.EntityFrameworkCore.Query.IMethodCallTranslator)
	System.Linq.Enumerable.SelectEnumerableIterator<TSource, TResult>.MoveNext()
	System.Linq.Enumerable.TryGetFirst<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource, bool>, out bool)
	System.Linq.Enumerable.FirstOrDefault<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource, bool>)
	Microsoft.EntityFrameworkCore.Query.RelationalMethodCallTranslatorProvider.Translate(Microsoft.EntityFrameworkCore.Metadata.IModel, Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression, System.Reflection.MethodInfo, System.Collections.Generic.IReadOnlyList<Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression>)
    ...
    [Call Stack Truncated]

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions