【问题标题】:How do I convert an Enum to an Int for use in an Expression.Equals operation?如何将 Enum 转换为 Int 以用于 Expression.Equals 操作?
【发布时间】:2010-09-03 11:02:59
【问题描述】:

我正在尝试在 C# 中动态构建一个表达式树,它被编译并用作 LINQ-to-SQL Where() 调用的谓词。问题是我试图将 Enum(以 int 作为其基础类型)直接与 Int 进行比较,但这失败并出现错误“成员 MyEnumType 没有支持的 SQL 转换”。

代码:

ParameterExpression param = Expression.Parameter(typeof(MyClass), "obj"); //input parameter - this exposes a property of the Enum type
MemberExpression enumMember = Expression.Property(param, "MyEnumProperty"); //used to get the Enum typed property from the parameter

//MISSING STEP TO CAST THE ENUM OF THE MEMBER EXPRESSION TO AN INT?

BinaryExpression binaryExpr = Expression.Equal(enumMember, Expression.Constant(1));
LambdaExpression<Func<MyClass, bool>> whereClause = Expression.Lambda(binaryExpr, param);

//when whereClause is used to filter LINQ-to-SQL results, the error is thrown

我对表达式树相当陌生,我无法弄清楚这一点。我试过使用

Expression.Convert(enumMember, typeof(int))

作为 BinaryExpression 的第一部分,但这并不能解决问题。

非常感谢任何帮助。

【问题讨论】:

  • 不知道如何在表达式树中获取枚举值
  • 经过更多挖掘,我认为这里的问题在于我对 LINQ-to-SQL 的理解,而不是表达式本身。我的实体对象上的 Enum 属性实际上不是数据库中的列;我认为这就是为什么它无法将其翻译为 where 子句的原因。我将采取不同的方法,但如果有人有任何见解,请随时分享。
  • 能否也提供 MyClass 的代码?您目前在帖子中的代码是相当样板的,从这里没什么可说的......

标签: c# linq-to-sql expression-trees


【解决方案1】:

简单地说,只要您已将枚举告知 LINQ-to-SQL(而不是将其映射为 int 并在C# 进行翻译)。例如,以下工作正常:

var param = Expression.Parameter(typeof(DomainObject));
var body = Expression.Equal(Expression.Property(param, "SomeProperty"),
                         Expression.Constant(YourEnumType.SomeEnum));
var predicate = Expression.Lambda<Func<DomainObject, bool>>(body, param);
var count = db.Table.Where(predicate).Count();

重点是我的SomeProperty 属性在dbml 中映射到枚举。只需用枚举类型(包括命名空间)改写类型名称。

同样,您不应该给它一个 1,而是给它一个类型化的枚举;例如:

Expression.Constant(Enum.ToObject(typeof(YourEnumType), 1))

(如果你只知道1

【讨论】:

    【解决方案2】:

    感谢 Marc Gravell。 (表达大师!)请参阅正确答案。 我对表达式例程进行了更改以适应这种情况。 普通属性或枚举。以防有人觉得这很有帮助

    public static Expression<Func<TPoco, bool>> GetEqualsPredicate<TPoco>(string propertyName,
                                                                              object value)
                                                                              Type fieldType )
        {     
    
            var parameterExp = Expression.Parameter(typeof(TPoco), @"t");   //(tpoco t)
            var propertyExp = Expression.Property(parameterExp, propertyName);// (tpoco t) => t.Propertyname
    
            var someValue = fieldType.IsEnum // get and eXpressionConstant.  Careful Enums must be reduced
                         ? Expression.Constant(Enum.ToObject(fieldType, value)) // Marc Gravell fix
                         : Expression.Constant(value, fieldType);
    
            var equalsExp = Expression.Equal(propertyExp,  someValue); // yes this could 1 unreadble state if embedding someValue determination
    
            return Expression.Lambda<Func<TPoco, bool>>(equalsExp, parameterExp); 
        }
    

    【讨论】:

      【解决方案3】:

      试试

      (int) enumMember
      

      【讨论】:

      • 这无法编译:“无法将类型 'System.Linq.Expressions.MemberExpression' 转换为 'int'”
      • 嘿,Sjoerd 是正确的...如果 enumMember 是一个实际的枚举,而不是一个的表达式树抽象。
      【解决方案4】:

      首先看看我的朋友,你必须将你的枚举修改为这样:

      public enum myenum : int
      {
      item1 = 0,
      item2 = 1
      }
      

      之后,您可以通过这种方式在 int 和该 eunm 之间进行转换:

      int x = (int) myenum.item1;
      

      【讨论】:

      • 这个答案显然是对这个问题的误解——OP 想知道如何使用表达式树来处理枚举类型。此外 - 枚举在 CLR 中自然属于“int”类型。这个问题是带有枚举的 C# 表达式的高搜索命中率,因此这个答案应该低于来自@philsoady 的更合适的答案
      猜你喜欢
      • 2014-07-20
      • 2018-12-13
      • 1970-01-01
      • 2017-08-25
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多