Как преобразовать Enum в Int для использования в Expression.Equals?

Я пытаюсь динамически строить дерево выражений в С#, которое компилируется и используется как предикат для вызова LINQ-to-SQL Where(). Проблема в том, что я пытаюсь сравнить Enum (с int как его базовый тип) непосредственно с Int, но это не с ошибкой "Member 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, но это не исправляет ее.

Любая помощь очень ценится.

Ответ 1

Просто вам не нужно, если вы сказали LINQ-to-SQL об enum (вместо того, чтобы отображать его как int и иметь отдельное свойство в С#, которое выполняет перевод). Например, следующее работает отлично:

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

Спасибо Марку Гравелю. (Expression Guru!) См. Правильный ответ. Я внес изменения в процедуру выражения, чтобы удовлетворить этот сценарий. Нормальные свойства или Enums. Если кто-то найдет это полезным

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

Try

(int) enumMember

Ответ 4

Посмотрите, мой друг, прежде всего, вы должны изменить свое перечисление таким образом:

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

после этого вы можете преобразовать между int и этим eunm таким образом:

int x = (int) myenum.item1;