c# - 如何将 LambdaExpression 转换为表达式> 在 C# 中
问题描述
我有以下代码LambdaExpression
在运行时根据我的SearchTerm
输入生成。我正在尝试构建一个动态where
子句。但是我被困在如何转换LambdaExpression
为Expression<Func<T,bool>>
private static Expression<Func<T,bool>> GetSearchAppliedQuery(IEnumerable<SearchTerm> terms)
{
var parameterExpression = ExpressionHelper.Parameter<T>();
Expression finalExpression = Expression.Constant(true);
Expression subExpression = Expression.Constant(false);
// Build up the LINQ Expression backwards:
// query = query.Where(x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value"));
foreach (var term in terms)
{
var hasMultipleTerms = term.EntityName?.Contains(',') ?? false;
if (hasMultipleTerms)
{
var entityTerms = term.EntityName.Split(',');
foreach (var entityTerm in entityTerms)
{
term.EntityName = entityTerm;
// x => x.Property == "Value" || x.AnotherProperty == "Value"
subExpression = Expression.OrElse(subExpression, GetComparisonExpression(term, parameterExpression));
}
}
// x => x.Property == "Value" && x.AnotherProperty == "Value"
finalExpression = Expression.AndAlso(finalExpression, hasMultipleTerms ? subExpression : GetComparisonExpression(term, parameterExpression));
}
// x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value")
var lambdaExpression = ExpressionHelper.GetLambda<T, bool>(parameterExpression, finalExpression);
// How to do this conversion??
Expression<Func<T,bool>> returnValue = ..??;
return returnValue;
}
我正在尝试应用上述方法的结果来获取查询,如下所示:
public static IQueryable<T> GetQuery(IQueryable<T> inputQuery, ISpecification<T> specification)
{
var query = inputQuery;
// modify the IQueryable using the specification's criteria expression
if (specification.Criteria != null)
{
query = query.Where(specification.Criteria);
}
...
return query;
}
所以我的最终查询看起来像,
query = query.Where(x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value"))
Edit-1:ExpressionHelper.GetLambda
按照@Ivan Stoev 的要求
添加方法
public static class ExpressionHelper
{
public static LambdaExpression GetLambda<TSource, TDest>(ParameterExpression obj, Expression arg)
{
return GetLambda(typeof(TSource), typeof(TDest), obj, arg);
}
public static LambdaExpression GetLambda(Type source, Type dest, ParameterExpression obj, Expression arg)
{
var lambdaBuilder = GetLambdaFuncBuilder(source, dest);
return (LambdaExpression)lambdaBuilder.Invoke(null, new object[] { arg, new[] { obj } });
}
private static MethodInfo GetLambdaFuncBuilder(Type source, Type dest)
{
var predicateType = typeof(Func<,>).MakeGenericType(source, dest);
return LambdaMethod.MakeGenericMethod(predicateType);
}
}
我错过了一些非常基本的东西还是做错了什么?请协助。
解决方案
ExpressionHelper.GetLambda<T, bool>
用于获取 lambda 表达式的方法隐藏了它的实际类型,这是所需的Expression<Func<T, bool>>
,因此您只需要使用强制转换运算符:
return (Expression<Func<T, bool>>)lambdaExpression;
或者更好的是,要么将结果类型更改为ExpressionHelper.GetLambda<TSource, TDest>
,Expression<Func<TSource, TDest>>
要么不使用该辅助方法 - 当您在编译时知道泛型类型参数时,如果泛型Expression.Lambda方法(ExpressionHelper.GetLambda<TSource, TDest>
似乎相当于 Expression.Lambda<Func<TSource, TDest>>
),只需使用一个,例如
var lambdaExpression = Expression.Lambda<Func<T, bool>>(parameterExpression, finalExpression);
推荐阅读
- flutter - flutter_tts 错误:无效参数:“SpeechSynthesisEvent”的实例
- sql - 计算分组减去 SQL 中的重叠所花费的总时间
- swagger - 如何在 swagger doc 中设置参数的字段类型?
- cypress - 为什么我的 finally() 块不起作用,即如果测试用例失败 finally 块也不会在 cypress 中执行
- html - 如何在Angular中更正以下表达式
- flutter - 如果尚未安装,是否有任何方法可以使用 QR 码安装应用程序,如果已安装重定向到应用程序中的特定屏幕?
- java - Libgdx 演员没有出现
- python - 如何在 VSCode 中将虚拟环境设置为默认解释器
- php - 我正在尝试将 php 中的变量传递给 sql 函数以获得 LIMIT 值
- swift - 如何在 SwiftUI 中使用 Firestore 创建子集合