【发布时间】:2013-10-29 01:22:32
【问题描述】:
我正在尝试使用表达式调用方法,并返回一个用于构建 sql 查询的字符串。
调用很简单
var actualUsers = db.Query<UserModel>( u => u.FirstName.Contains( "ues" ) && u.LastName == "" );
在我的评估器中,我可以使用 BinaryExpression 评估器非常轻松地获得 "LastName = ''"。
但是,当我尝试从 MethodCalLExpression 中获取“名字”时,我可以通过使用 expression.Object.ToString(); 得到最接近的 u.FirstName
获取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);
}
【问题讨论】:
-
您应该访问
expression.Object以使用ExpressionVisitor获取该值,您可以支持子表达式的所有可能值,而不是硬编码仅在那个非常有效的东西具体实例。 -
@Servy,我从来没有做过这样的事情,现在正处于一个陡峭的学习曲线上。我很想知道如何连接 ExpressionVisitor。