在.Net 5.0.4实体框架查询中使用具有多个值的[Flags]



我有一个具有[Flags]属性的枚举,如下所示:

[Flags]
public enum FlagStatus

{

Value1 = 1

, Value2 = 2

, Value3 = 4

}

我对EF的查询是这样的:

x => x.Status.HasFlag(flagStatus)

现在,如果我设置了flagStatus = FlagStatus.Value1,则查询工作正常,因为我将值设置为1(。

@__request_Status_0 = 1
WHERE ([o].[StatusId] & @__request_Status_0) = @__request_Status_0)

但是,如果我将其设置为flagStatus = FlagStatus.Value1 | FlagStatus.Value3,则查询不会返回任何结果,因为翻译后的SQL如下所示:

@__request_Status_0 = 5
WHERE ([o].[StatusId] & @__request_Status_0) = @__request_Status_0)

由于这不是Status字段的有效Id int,因此不会返回任何结果。

所以现在的问题是:.HasFlag不应该由.Net5EF支持吗?还是由于某种原因,按位操作仅限于一个值?如果是这样,为什么要支持比特操作?

我可能错过了什么,但我就是没看到

难道.HasFlag不应该由.Net5 EF 支持吗

支持意味着转换为SQL,而不是抛出运行时异常,所以很明显是这样。

由于某种原因是按位操作,仅限于一个值

不,不是。但当与多个值一起使用时,它的含义与您预期的不同。Enum.HasFlags CLR方法的文档说明它返回

true,如果在标志中设置的一个或多个位字段也在当前实例中设置;否则为false

然后在备注中:

HasFlag方法返回以下布尔表达式的结果。

thisInstance And flag = flag

这正是EF Core正在做的事情。

将其转换为简单单词,它检查标志中的所有位是否存在值(集合的等效All操作(。而您似乎期望它具有Any语义。

很快,HasFlag表示AllAny没有专用的方法,所以你应该使用它的直接位操作等价物

(value & flags) != 0

在您的样品中

x => (x.Status & flagStatus) != 0

相关内容

  • 没有找到相关文章

最新更新