1

Expression を使用してメソッドを呼び出し、SQL クエリを作成するための文字列を返そうとしています。

呼び出しは簡単です

var actualUsers = db.Query<UserModel>( u => u.FirstName.Contains( "ues" ) && u.LastName == "" );

"LastName = ''"のエバリュエーターでは、BinaryExpression エバリュエーターを使用して非常に簡単に取得できます。

ただし、から「FirstName」を取得しようとするとMethodCalLExpression、最も近いのは次u.FirstNameを使用することですexpression.Object.ToString();

MethodCallExpression のプロパティ名を取得する正しい方法は何ですか?

これが私がこれまでに得た方法です。

    public static IList<TModel> Query<TModel> ( this IDbProvider iDbProvider, Expression<Func<TModel, object>> exp ) where TModel : class, new()
    {
        // SELECT * FROM [Users] WHERE FirstName LIKE '%ues%'
        // Should return the "Guest" user.

        var sqlExpression = GetSqlExpression( exp.Body );
        return // ....
    }

    private static string GetSqlExpression ( Expression expression )
    {
        if ( expression is MethodCallExpression )
        {
            return GetMethodCallOperator( ( MethodCallExpression )expression );
        }
        // more crap...
    }

    private static string GetMethodCallOperator ( MethodCallExpression expression )
    {
        var lambda = Expression.Lambda( expression.Arguments[0] );
        var compiledExpression = lambda.Compile().DynamicInvoke();


        var commandText = string.Empty;
        var key = expression.Object.ToString(); // "u.FirstName" -- should just be "FirstName"
        var value = compiledExpression.ToString(); // "ues"
        switch ( expression.Method.Name )
        {
            case "Contains":
                commandText = "[{0}] LIKE '%{1}%'";
                break;
        }

        // return "[FirstName] LIKE '%ues%'";
        return string.Format(commandText ,key, value);
    }
4

1 に答える 1

3

あなたの例では:

var memberAccess = expression.Object as MemberExpression;
Console.WriteLine(memberAccess.Member.Name); //will print FirstName

MemberExpressionは、フィールドまたはプロパティへのアクセスを記述するクラスです。プロパティ名にアクセスするために使用します。u.FirstName.Contains( "ues" )私は、解析された式を次のように渡すと仮定しますGetMethodCallOperator

完全な例:

void PrintName(Expression<Func<Foo, bool>> func)
{
    var methodCall = func.Body as MethodCallExpression;
    var property =  methodCall.Object as MemberExpression;
    Console.WriteLine (property.Member.Name);
}

PrintName(u => u.FirstName.Contains( "ues" )); //prints FirstName

どこ:

class Foo
{
    public string FirstName { get; set; }
}
于 2013-10-28T17:17:17.393 に答える