简体   繁体   English

Expression.Call,Int32和Enum

[英]Expression.Call, Int32 and Enum

Can't figure out how to build an expression that compares an enum type with an int. 无法弄清楚如何构建将枚举类型与整数进行比较的表达式。 I have a MVC site with Kendo components embedded. 我有一个嵌入Kendo组件的MVC网站。 In the view-class, the property is an ENUM, but the view returns an Int32 (the source is a Kendo IFilterDescriptor). 在视图类中,属性为ENUM,但视图返回Int32(源为Kendo IFilterDescriptor)。

So the problem is...: I receive an int from the view, build the expression, that fails because an enum is expected. 所以问题是...:我从视图中接收到一个int,构建表达式,由于期望枚举,该操作失败。 Fix this by converting the int to its enum representation, but then it fails when querying the database, because the database expect an Int32. 通过将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);

From what I understand, Expression.Call() should be able to fix this, I just can't figure out how to do this. 据我了解,Expression.Call()应该可以解决此问题,但我只是想不出如何做到这一点。

Any help would be appreciated. 任何帮助,将不胜感激。

BR Peter 彼得

UPDATE 更新

Converting the value like below, does fix the expression problem (the "The binary operator Equal is not defined for the types..." error), but then I get a new error querying the database: "Type mismatch in NHibernate.Criterion.SimpleExpression: Status expected type System.Int32, actual type...". 像下面那样转换值,确实解决了表达式问题(“类型未定义二进制运算符Equal ...”错误),但是随后我在查询数据库时遇到了一个新错误:“ NHibernate.Criterion中的类型不匹配。 SimpleExpression:状态预期类型为System.Int32,实际类型为...”。

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

The fix, as I see it, is either by building my own compare (Expression.Call ?) or by telling that the type (in item.Member) is an int and not an enum, but I don't know how or if this is the right way. 如我所见,此修复程序是通过建立自己的比较(Expression.Call?)或通过告知类型(在item.Member中)是int而非枚举来实现的,但我不知道该怎么做或是否这是正确的方法。 Thanks. 谢谢。

UPDATE UPDATE 更新更新

It seems like that the second part of the problem is due to NHibernate.QueryOver and its limitations. 问题的第二部分似乎是由于NHibernate.QueryOver及其局限性引起的。 Once changed to NHibernate.Linq, the query part of the problem, went away. 一旦更改为NHibernate.Linq,问题的查询部分就消失了。

As for the Expression part I have fixed the problem by adding an attribute to the property telling how the value should be converted. 至于表达式部分,我通过在属性中添加一个属性来说明应如何转换值,从而解决了该问题。 I am not using Expression.Convert (but I could have), the conversion happens in the received filter description before building the expression. 我没有使用Expression.Convert(但我可以使用),在生成表达式之前,转换发生在接收到的过滤器描述中。

Thanks for your time and help. 感谢您的时间和帮助。 I will accept the answers related to Expression.Convert since it could fix the problem. 我将接受与Expression.Convert相关的答案,因为它可以解决问题。 I still do want to understand the Expression.Call() method - so please feel free to comment on that. 我仍然想了解Expression.Call()方法-因此请随时对此发表评论。 Thanks. 谢谢。

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

Wouldn't this do the trick? 这不会成功吗?

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

I don't exactly see your enum you are comparing to, is it item.Value? 我没有看到您正在比较的枚举,它是item.Value吗?

You can always cast the value of an enum to a number to compare it to a number or feed it into systems that don't recognize enums: 您始终可以将枚举的值强制转换为数字,以将其与数字进行比较或将其输入不识别枚举的系统中:

enum Blah
{
    Tom,
    Rick,
    Harry
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM