Comment convertir un enum en un int pour l'utiliser dans une opération Expression.Equals?

c# expression-trees linq-to-sql

Question

J'essaie de construire dynamiquement un arbre d'expression en C #, qui est compilé et utilisé comme prédicat pour l'appel Where () de LINQ-to-SQL. Le problème est que j'essaie de comparer un Enum (avec int comme type sous-jacent) directement à un Int, mais cela échoue avec l'erreur "Le membre MyEnumType n'a pas de traduction prise en charge en SQL".

Code:

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

Je suis assez nouveau pour les arbres d'expression et je ne peux pas comprendre cela. J'ai essayé d'utiliser

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

en tant que première partie de BinaryExpression mais cela ne le résout pas.

Toute aide est très appréciée.

Réponse d'expert

Simplement, vous ne devriez pas avoir à le faire, tant que vous avez dit à LINQ-to-SQL à propos de l'énum (plutôt que de le mapper en tant int et d'avoir une propriété séparée en C # qui effectue la traduction). Par exemple, ce qui suit fonctionne bien:

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();

Le point principal est que ma propriété SomeProperty est mappée dans le dbml vers l'énum. Remplacez simplement le nom du type par le type enum (y compris l'espace de noms).

De même, vous ne devriez pas lui donner un 1, mais plutôt l'énumération dactylographiée; par exemple:

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();

(si tout ce que vous savez est 1 )


Réponse populaire

Merci à Marc Gravell. (Expression Guru!) Voir la réponse correcte. J'ai modifié la routine d’expression afin de prendre en charge ce scénario. Propriétés normales ou Enums. Incase quelqu'un trouve cela utile

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); 
    }



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi