Expression.Call,Int32和Enum

时间:2015-03-09 14:16:54

标签: c# fluent-nhibernate expression kendo-grid

无法弄清楚如何构建一个将枚举类型与int进行比较的表达式。我有一个嵌入了Kendo组件的MVC站点。在视图类中,属性是ENUM,但视图返回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彼得

更新

转换如下所示的值,确实修复了表达式问题(“二进制运算符Equal没有为类型定义...”错误),但后来我得到一个新的错误查询数据库:“NHibernate中的类型不匹配.Criterion.SimpleExpression:状态预期类型System.Int32,实际类型......“。

exp = Expression.Equal(member, Expression.Convert(value, typeof(MyEnum)));

我认为修复是通过构建我自己的比较(Expression.Call?)或者告诉类型(在item.Member中)是int而不是枚举,但我不知道如何或如果这是正确的方式。 感谢。

更新更新

似乎问题的第二部分是由于NHibernate.QueryOver及其局限性。一旦改为NHibernate.Linq,问题的查询部分就消失了。

至于Expression部分,我已经通过向属性添加一个属性来解决问题,该属性告诉我们应该如何转换值。我没有使用Expression.Convert(但我可以),在构建表达式之前,转换发生在收到的过滤器描述中。

感谢您的时间和帮助。我将接受与Expression.Convert相关的答案,因为它可以解决问题。我仍然想要了解Expression.Call()方法 - 所以请随意评论。感谢。

3 个答案:

答案 0 :(得分:3)

您可以使用Expression.Convert转换枚举type to an int`的表达式(假设枚举的基础类型为int)。

答案 1 :(得分:2)

不会这样做吗?

MemberExpression member = Expression.Convert(
                            Expression.Property(pe, item.Member), typeof(int);
ConstantExpression value = Expression.Constant((int)item.Value);

答案 2 :(得分:1)

我没有完全看到你要比较的枚举,是item.Value吗?

您始终可以将枚举值转换为数字,以将其与数字进行比较,或将其输入到不识别枚举的系统中:

enum Blah
{
    Tom,
    Rick,
    Harry
}

if ((Int32)Blah.Tom == 0)
{
}