gpt4 book ai didi

c# - 通过 System.Linq.Expressions.Expression 创建表达式时,LINQ to Entities 无法识别方法 'Boolean HasFlag(System.Enum)'

转载 作者:太空狗 更新时间:2023-10-30 01:00:25 25 4
gpt4 key购买 nike

我们正在使用 System.Linq.Expressions.Expression 构建自定义表达式,这些表达式应用于我们的 IQueryable.Where() .

我想要实现的是,在 .Where() 中使用的属性上应用 .HasFlag() 方法 ( introduced in EF 6.1 )表达。

我有以下代码:

var memberExpression = propertyExpression as MemberExpression;
var targetType = memberExpression?.Type ?? typeof(decimal?);
var value = Enum.Parse(type, searchValue);
var hasFlagMethod = targetType.GetMethod(nameof(Enum.HasFlag));
var hasFlagExpression = Expression.Call(propertyExpression, hasFlagMethod, Expression.Convert(Expression.Constant(value), typeof(Enum)));

propertyExpression 的值显示为 {x.Type}hasFlagMethod 显示为 {Boolean HasFlag (System.Enum)} 我觉得都不错。

hasFlagExpression 的值是 {x.Type.HasFlag(Convert(Foo))} 除了 Convert(Foo ) 部分,但这样做是必要的,否则我会得到另一个异常,它提示参数不能应用于此方法,因为它不是 System.Enum

当我们用这个 .Where() 枚举 IQueryable 时,我们得到以下异常:

NotSupportedException: LINQ to Entities does not recognize the method
'Boolean HasFlag(System.Enum)' method, and this method cannot
be translated into a store expression.

直接在 IQueryable 上调用它是可行的(我们还使用 EF 6.1,它添加了对 Enum.HasFlag() 的支持)

Entities.Where(x => x.Type.HasFlag(BarEnum.Foo));

但是这样调用它不是一种选择,因为它需要对我们所有的实体都是通用的。 (我们根据数据表中过滤的列将那些 .Where() 条件放在一起)

最佳答案

MethodInfo 之间有一个不易察觉的小区别。代码中的 HasFlag 方法和编译器生成的方法。 ReflectedType前者的属性是 typeof(YourEnum),而后者是 typeof(Enum)DeclaringType两种情况下的属性都是相同的 - typeof(Enum),因此显示调试,但这足以破坏 EF 查询翻译器。

要解决这个问题,只需更改

var hasFlagMethod = targetType.GetMethod(nameof(Enum.HasFlag));

var hasFlagMethod = typeof(Enum).GetMethod(nameof(Enum.HasFlag));

关于c# - 通过 System.Linq.Expressions.Expression 创建表达式时,LINQ to Entities 无法识别方法 'Boolean HasFlag(System.Enum)',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46450104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com