【发布时间】:2020-06-25 18:59:08
【问题描述】:
我正在尝试编写动态查询,但在处理查询的 OrderBy 部分中的动态类型时遇到了问题。我已经看到一些使用方法调用表达式的解决方案,这可能对我有用,但我不知道如何将其融入我现有的代码中,我在任一端都使用方法链接。我可以只使用 dynamic 作为我的类型,但我认为这不适用于 Nullable 类型。
public async Task<IEnumerable<MyEntityModel>> GetEntities(QueryEntityResource request)
{
IQueryable<MyEntityModel> queryableData = ...;
Expression whereLambdaExp = ...;
queryableData = queryableData.Where(whereLambdaExp);
ParameterExpression param = Expression.Parameter(typeof(MyEntityModel));
PropertyInfo property = typeof(MyEntityModel).GetProperty(request.sortModel.ColId);
Expression propExpr = Expression.Property(param, property);
var lambdaExpression = Expression.Lambda<Func<MyEntityModel, dynamic>>(propExpr , new ParameterExpression[] { param }); // can't use dynamic
// Errors here; can't use dynamic type in lambda expression -- Need to specify types
if (request.sortModel.Sort == "asc")
{
queryableData = queryableData.OrderBy(lambdaExpression);
}
if (request.sortModel.Sort == "desc")
{
queryableData = queryableData.OrderByDescending(lambdaExpression);
}
queryableData = queryableData.Skip(request.StartRow).Take(request.EndRow - request.StartRow);
return queryableData.ToListAsync();
}
如果我使用动态,它将不适用于我的可为空类型:
System.ArgumentException:“System.Nullable`1[System.Int32]”类型的表达式不能用于返回类型“System.Object”
【问题讨论】:
-
仅供参考,Expression.Lambda 有一个
params变体,它将为您创建数组,因此您不需要new ParameterExpression[](并且,您不需要ParameterExpression,因为new[]可以从{}中的表达式推断出数组类型。 -
是的,构建
Expressions 以与 LINQ 查询运算符一起使用的问题是它向上传播(像病毒一样)。由于OrderBy是通用的,因此您需要对OrderBy<TSource,TKey>进行正确的方法调用并固定通用属性,因此您还必须将其构建为Expression树并且因为queryableData是IQueryable<T>将需要替换Expression。 -
@NetMage 请给我一个代码示例以及它如何适合我现有的代码?