简体   繁体   中英

EF Core + enum parameter in where query

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:

  • 3.1 (EF 3.x)
     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM