Как преобразовать Enum в Int для использования в операции Expression.Equals? - PullRequest
10 голосов
/ 03 сентября 2010

Я пытаюсь динамически построить дерево выражений в 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, но это не исправляет это.

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

Ответы [ 4 ]

6 голосов
/ 09 сентября 2010

Просто вам не нужно этого делать, если вы сообщили 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 на перечисление. Просто замените имя типа типом enum (включая пространство имен).

Точно так же вы должны указывать не 1, а типизированное перечисление; например:

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

(если все, что вы знаете, это 1)

1 голос
/ 22 декабря 2013

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

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); 
    }
0 голосов
/ 04 сентября 2010

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

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

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

int x = (int) myenum.item1;
0 голосов
/ 03 сентября 2010

Попробуйте

(int) enumMember
...