I'm struggling to add an enum to a where
condition I have on my queries.
I have the following definition for my class:
public enum Status
{
Pending,
Confirmed
}
public class Deposit
{
public Status Status { get; set; }
}
Whenever I add a where
condition with a raw enum value, like in the below example, it works perfectly:
query.Where(d => d.Status == Status.Completed);
// Generated query:
Executed DbCommand (40ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT d.*
FROM deposit AS d
WHERE d.status = 'Completed'
Whenever I try to add this enum value as a parameter, it fails in the following query:
query.Where(d => d.Status == input.Status);
// Generated query:
Failed executing DbCommand (244ms) [Parameters=[@__searchInput_Status_Value_0='Completed' (Nullable = false)], CommandType='Text', CommandTimeout='30']
SELECT d.*
FROM deposit AS d
WHERE d.status = @__searchInput_Status_Value_0
If I try to convert this enum in my model creation, I keep having the same error, either with string
or int
conversion:
For string conversions:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = text
For int conversions:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion<int>();
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = integer
Can somebody give some light on it? Thank y'all!! :)
It seems like this is an issue in the PostgreSQL EF Core provider.
The following workaround should solve it, but there are version limitations; See notes below.
Map:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
Code:
var statusFilter = new[] { input.Status };
query.Where(d => statusFilter.Contains(d.Status));
Notes regarding affected versions
The workaround above works for Npgsql.EntityFrameworkCore.PostgreSQL
versions 3.0, 5.0 (and hopefully 6.0, did not check it)
Versions 3 and 5 translate the code differently:
3.0 (with EF 3.x)
info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT d.* FROM deposit AS d WHERE d.status IN ('Completed')
5.0 (with EF 5.x)
info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (15ms) [Parameters=[@__statusFilter_0='?' (DbType = Object)], CommandType='Text', CommandTimeout='30'] SELECT d.* FROM deposit AS d WHERE b.status = ANY (@__statusFilter_0)
It won't work in 3.1; it fails with pretty much the same error:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (18ms) [Parameters=[@__statusFilter_0='?' (DbType = Object)], CommandType='Text', CommandTimeout='30'] SELECT d.* FROM deposit AS d WHERE b.status = ANY (@__statusFilter_0) fail: Microsoft.EntityFrameworkCore.Query[10100] An exception occurred while iterating over the results of a query for <...>. Npgsql.PostgresException (0x80004005): 42883: operator does not exist: character varying = integer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.