Skip to content

Can't ignore an ImmutableArray<> property in entity configuration #35329

@ErroneousFatality

Description

@ErroneousFatality

I want to have a pass-through property in my code for developer usage convenience, thus I want to ignore the property in the entity configuration because I don't need it mapped to the database.
EFCore throws an exception during migration building saying it can't use the property because it doesn't know how to compare the generic immutable array type with an object.

When I change the ignored property's type to IReadOnlyList<Role>/IReadOnlyCollection<Role> everything works fine.

Code examples

public sealed class Example 
{
    public Guid Id { get; private set; }

    public ImmutableArray<Role> Roles { 
        get => Enum.GetValues<Role>().Where(flag => RoleFlags.HasFlag(flag)).ToImmutableArray(); 
        internal set => RoleFlags = value.Aggregate((flags, role) => flags | role);
    }
    public Role RoleFlags { get; private set; }
}
internal sealed class ExampleConfiguration : IEntityTypeConfiguration<Example>
{
    public void Configure(EntityTypeBuilder<Example> example)
    {
        example.Ignore(e => e.Roles);
    }
}
[Flags]
public enum Role : byte
{
    Administrator = 1,
    Customer = 2
}

Stack trace and verbose output

Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create a 'DbContext' of type 'PostgreSqlDataContext'. The exception 'Exception has been thrown by the target of an invocation.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
 ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidOperationException: Reference equality is not defined for the types 'System.Collections.Immutable.ImmutableArray`1[Domain.Entities.Users.Role]' and 'System.Object'.
   at System.Linq.Expressions.Expression.ReferenceEqual(Expression left, Expression right)
   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 Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType, KeyValuePair`2 contextPair)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace, Boolean dryRun)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create a 'DbContext' of type 'PostgreSqlDataContext'. The exception 'Exception has been thrown by the target of an invocation.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

Provider and version information

EF Core version: 9.0.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 9.0.2
Target framework: .NET 9.0
Operating system: Windows 11 24H2
IDE: Visual Studio 2022 17.12.3

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions