Expression.Call、Int32 和枚举
Expression.Call, Int32 and Enum
无法弄清楚如何构建将枚举类型与 int 进行比较的表达式。我有一个嵌入了 Kendo 组件的 MVC 站点。在视图-class 中,属性 是一个ENUM,但视图returns 是一个Int32(来源是一个Kendo IFilterDescriptor)。
所以问题是...:我从视图中收到一个 int,构建表达式,但失败了,因为需要一个枚举。通过将 int 转换为其枚举表示来修复此问题,但随后在查询数据库时失败,因为数据库需要 Int32。
public static Expression<Func<DOMAIN, bool>> GetExpressionsFromFilterDescription<DOMAIN, VIEW>(this IEnumerable<IFilterDescriptor> _this)
{
Expression expressions = null;
ParameterExpression pe = Expression.Parameter(typeof(DOMAIN), "x");
foreach (FilterDescriptor item in _this)
{
MemberExpression member = Expression.Property(pe, item.Member);
ConstantExpression value = Expression.Constant(item.Value);
Expression exp = null;
switch (item.Operator)
{
case FilterOperator.IsEqualTo:
exp = Expression.Equal(member, value);
据我了解,Expression.Call() 应该可以解决这个问题,但我不知道该怎么做。
如有任何帮助,我们将不胜感激。
BR 彼得
更新
像下面那样转换值,确实解决了表达式问题("The binary operator Equal is not defined for the types..." 错误),但随后我在查询数据库时遇到新错误:"Type mismatch in NHibernate.Criterion.SimpleExpression: Status expected type System.Int32, actual type...".
exp = Expression.Equal(member, Expression.Convert(value, typeof(MyEnum)));
如我所见,解决方法是通过构建我自己的比较 (Expression.Call ?) 或告知类型(在 item.Member 中)是 int 而不是枚举,但我不知道这是如何或是否是正确的方法。
谢谢
更新更新
问题的第二部分似乎是由于 NHibernate.QueryOver 及其局限性造成的。一旦更改为 NHibernate.Linq,问题的查询部分就消失了。
至于表达式部分,我已通过向 属性 添加一个属性来告知应如何转换值,从而解决了该问题。我没有使用 Expression.Convert(但我可以),转换发生在构建表达式之前收到的过滤器描述中。
感谢您的宝贵时间和帮助。我会接受与 Expression.Convert 相关的答案,因为它可以解决问题。我仍然想了解 Expression.Call() 方法 - 所以请随时对此发表评论。谢谢
我不太清楚你要比较的枚举,是吗item.Value?
您始终可以将枚举的值转换为数字以将其与数字进行比较或将其输入到不识别枚举的系统中:
enum Blah
{
Tom,
Rick,
Harry
}
if ((Int32)Blah.Tom == 0)
{
}
您可以使用 Expression.Convert
来转换枚举的表达式type to an
int`(假设枚举的基础类型是 int)。
这样不行吗?
MemberExpression member = Expression.Convert(
Expression.Property(pe, item.Member), typeof(int);
ConstantExpression value = Expression.Constant((int)item.Value);
无法弄清楚如何构建将枚举类型与 int 进行比较的表达式。我有一个嵌入了 Kendo 组件的 MVC 站点。在视图-class 中,属性 是一个ENUM,但视图returns 是一个Int32(来源是一个Kendo IFilterDescriptor)。
所以问题是...:我从视图中收到一个 int,构建表达式,但失败了,因为需要一个枚举。通过将 int 转换为其枚举表示来修复此问题,但随后在查询数据库时失败,因为数据库需要 Int32。
public static Expression<Func<DOMAIN, bool>> GetExpressionsFromFilterDescription<DOMAIN, VIEW>(this IEnumerable<IFilterDescriptor> _this)
{
Expression expressions = null;
ParameterExpression pe = Expression.Parameter(typeof(DOMAIN), "x");
foreach (FilterDescriptor item in _this)
{
MemberExpression member = Expression.Property(pe, item.Member);
ConstantExpression value = Expression.Constant(item.Value);
Expression exp = null;
switch (item.Operator)
{
case FilterOperator.IsEqualTo:
exp = Expression.Equal(member, value);
据我了解,Expression.Call() 应该可以解决这个问题,但我不知道该怎么做。
如有任何帮助,我们将不胜感激。
BR 彼得
更新
像下面那样转换值,确实解决了表达式问题("The binary operator Equal is not defined for the types..." 错误),但随后我在查询数据库时遇到新错误:"Type mismatch in NHibernate.Criterion.SimpleExpression: Status expected type System.Int32, actual type...".
exp = Expression.Equal(member, Expression.Convert(value, typeof(MyEnum)));
如我所见,解决方法是通过构建我自己的比较 (Expression.Call ?) 或告知类型(在 item.Member 中)是 int 而不是枚举,但我不知道这是如何或是否是正确的方法。 谢谢
更新更新
问题的第二部分似乎是由于 NHibernate.QueryOver 及其局限性造成的。一旦更改为 NHibernate.Linq,问题的查询部分就消失了。
至于表达式部分,我已通过向 属性 添加一个属性来告知应如何转换值,从而解决了该问题。我没有使用 Expression.Convert(但我可以),转换发生在构建表达式之前收到的过滤器描述中。
感谢您的宝贵时间和帮助。我会接受与 Expression.Convert 相关的答案,因为它可以解决问题。我仍然想了解 Expression.Call() 方法 - 所以请随时对此发表评论。谢谢
我不太清楚你要比较的枚举,是吗item.Value?
您始终可以将枚举的值转换为数字以将其与数字进行比较或将其输入到不识别枚举的系统中:
enum Blah
{
Tom,
Rick,
Harry
}
if ((Int32)Blah.Tom == 0)
{
}
您可以使用 Expression.Convert
来转换枚举的表达式type to an
int`(假设枚举的基础类型是 int)。
这样不行吗?
MemberExpression member = Expression.Convert(
Expression.Property(pe, item.Member), typeof(int);
ConstantExpression value = Expression.Constant((int)item.Value);