EF Core + where 查询中的枚举参数
EF Core + enum parameter in where query
我正在努力将枚举添加到查询中的 where
条件。
我的 class 定义如下:
public enum Status
{
Pending,
Confirmed
}
public class Deposit
{
public Status Status { get; set; }
}
每当我添加带有原始枚举值的 where
条件时,如下例所示,它都能完美运行:
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'
每当我尝试将此枚举值添加为参数时,它都会在以下查询中失败:
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
如果我尝试在我的模型创建中转换此枚举,我会一直遇到相同的错误,使用 string
或 int
转换:
对于字符串转换:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = text
对于 int 转换:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion<int>();
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = integer
有人可以解释一下吗?
谢谢大家!! :)
这似乎是 PostgreSQL EF Core 提供程序中的一个问题。
下面的解决方法应该可以解决,但是有版本限制;请参阅下面的注释。
地图:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
代码:
var statusFilter = new[] { input.Status };
query.Where(d => statusFilter.Contains(d.Status));
有关受影响版本的说明
上述解决方法适用于 Npgsql.EntityFrameworkCore.PostgreSQL
版本 3.0、5.0(希望是 6.0,未检查)
版本 3 和版本 5 以不同方式翻译代码:
3.0(带 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(带 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)
它在 3.1 中不起作用;它几乎失败了 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
以防将来有人(包括我自己)在过滤 EF Core 中映射为字符串的 Postgres 枚举数组时遇到问题,我将明确表示上述解决方法也适用于数组,即:
这行不通
query.Where(d => d.SupportedDepositTypes.Contains(DepositType.RecurringDeposit));
但这行得通
var filterValue = DepositType.RecurringDeposit;
query.Where(d => d.SupportedDepositTypes.Contains(filterValue));
我正在努力将枚举添加到查询中的 where
条件。
我的 class 定义如下:
public enum Status
{
Pending,
Confirmed
}
public class Deposit
{
public Status Status { get; set; }
}
每当我添加带有原始枚举值的 where
条件时,如下例所示,它都能完美运行:
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'
每当我尝试将此枚举值添加为参数时,它都会在以下查询中失败:
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
如果我尝试在我的模型创建中转换此枚举,我会一直遇到相同的错误,使用 string
或 int
转换:
对于字符串转换:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = text
对于 int 转换:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion<int>();
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: enum_deposit_status = integer
有人可以解释一下吗? 谢谢大家!! :)
这似乎是 PostgreSQL EF Core 提供程序中的一个问题。
下面的解决方法应该可以解决,但是有版本限制;请参阅下面的注释。
地图:
modelBuilder.Entity<Deposit>()
.Property(d => d.Status)
.HasConversion(new EnumToStringConverter<Status>());
代码:
var statusFilter = new[] { input.Status };
query.Where(d => statusFilter.Contains(d.Status));
有关受影响版本的说明
上述解决方法适用于 Npgsql.EntityFrameworkCore.PostgreSQL
版本 3.0、5.0(希望是 6.0,未检查)
版本 3 和版本 5 以不同方式翻译代码:
3.0(带 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(带 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)
它在 3.1 中不起作用;它几乎失败了 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
以防将来有人(包括我自己)在过滤 EF Core 中映射为字符串的 Postgres 枚举数组时遇到问题,我将明确表示上述解决方法也适用于数组,即:
这行不通
query.Where(d => d.SupportedDepositTypes.Contains(DepositType.RecurringDeposit));
但这行得通
var filterValue = DepositType.RecurringDeposit;
query.Where(d => d.SupportedDepositTypes.Contains(filterValue));