-
Notifications
You must be signed in to change notification settings - Fork 249
Closed
Copy link
Milestone
Description
Hey,
I found problem with the 9.x release.
We have a "PascalCase" naming convention for tables and enums. (yeah probably not good, but we have it)
When i set a cusom name that has no upper case letter it works.
When I search for models with some enums:
List<MyEnum> listOfEnums = [MyEnum.value1];
var result = await context.Set<MyEntity>().AsQueryable().Where(item => listOfEnums.Contains(item.MyEnum)).ToListAsync();
I receive an error:
Unhandled exception. Npgsql.PostgresException (0x80004005): 42883: Operator existiert nicht: doller_test."MyEnum" = integer
POSITION: 89
at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`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 C:\Users\MicFiller\Documents\Test\MariaDbTest\PostgresTest\Program.cs:line 51
at Program.<Main>(String[] args)
Exception data:
Severity: FEHLER
SqlState: 42883
MessageText: Operator existiert nicht: doller_test."MyEnum" = integer
Hint: Kein Operator stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen.
Position: 89
File: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\parser\parse_oper.c
Line: 731
Routine: op_error
The problem is that the generated sql somehow assumes that the parameter is an int:
Failed executing DbCommand (72ms) [Parameters=[@__listOfEnums_0={ '0' } (DbType = Object)], CommandType='Text', CommandTimeout='30']
SELECT m."Id", m."MyEnum", m."Name"
FROM doller_test."MyEntity" AS m
WHERE m."MyEnum" = ANY (@__listOfEnums_0)
__listOfEnums_0 should be "value1"
Setup to reproduce:
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(
"Host=localhost;Database=postgres;Username=postgres;Password=postgres",
option => { RegisterEnum<MyEnum>(option); });
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("doller_test");
modelBuilder.Entity<MyEntity>(_ => { });
base.OnModelCreating(modelBuilder);
}
private static void RegisterEnum<TEnum>(NpgsqlDbContextOptionsBuilder optionsBuilder)
where TEnum : struct, Enum
{
// works
// optionsBuilder.MapEnum<TEnum>("enum", schemaName: "doller_test");
// does not work
optionsBuilder.MapEnum<TEnum>(typeof(TEnum).Name, schemaName: "doller_test");
}
}
public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
public MyEnum MyEnum { get; set; }
}
public enum MyEnum
{
value1 = 0,
value2 = 1
}
// Program.cs
var context = new MyDbContext();
await context.Database.MigrateAsync();
var postgresConnection = (NpgsqlConnection)context.Database.GetDbConnection();
if (postgresConnection.State != ConnectionState.Open)
{
postgresConnection.Open();
}
postgresConnection.ReloadTypes();
List<MyEnum> listOfEnums = [MyEnum.value1];
var result = await context.Set<MyEntity>().AsQueryable().Where(item => listOfEnums.Contains(item.MyEnum)).ToListAsync();