Как преобразовать 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;