gpt4 book ai didi

c# - 将 Select 方法用于动态查询和表达式树

转载 作者:太空狗 更新时间:2023-10-29 23:40:01 24 4
gpt4 key购买 nike

我正在尝试使用表达式树来创建动态查询以匹配以下语句:

var items = data.Where(i => i.CoverageType == 2).Select(i => i.LimitSelected);

我可以创建 where 方法并从中获取结果;但是,我无法创建选择方法。

这是我的 where 方法:

var parm = Expression.Parameter(typeof(BaseClassData), "baseCoverage");

var queryData = data.AsQueryable();

var left = Expression.Property(parm, "CoverageType");
var right = Expression.Constant(2m);
var e1 = Expression.Equal(left, right);

var whereMethod = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryData.ElementType },
queryData.Expression,
Expression.Lambda<Func<BaseClassData, bool>>(e1, new ParameterExpression[] { parm }));

这就是我在选择方法中使用的:

var selectParm = Expression.Property(parm, "LimitSelected");
var selectMethod = Expression.Call(
typeof(Enumerable),
"Select",
new Type[]{typeof(BaseClassData), typeof(decimal)},
whereMethod,
Expression.Lambda<Func<BaseClassData, decimal>>(selectParm, new ParameterExpression[]{ parm})

);

当我运行代码时出现此错误:

No generic method 'Select' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

我也试过将 Enumerable 更改为 Queryable,但我得到了同样的错误。

最佳答案

无需使用Expression.Call,直接构造Expression Tree即可;我创建了一个静态方法来帮助我生成动态查询:

public static void Test(string[] args) {
using (var db = new DBContext()) {
//query 1
var query1 = db.PrizeTypes.Where(m => m.rewards == 1000).Select(t => t.name);

//query 2 which equal to query 1
Expression<Func<PrizeType, bool>> predicate1 = m => m.rewards == 1000;
Expression<Func<PrizeType, string>> selector1 = t => t.name;
var query2 = db.PrizeTypes.Where(predicate1).Select(selector1);
Console.WriteLine(predicate1);
Console.WriteLine(selector1);
Console.WriteLine();

//query 3 which equal to query 1 and 2
Expression<Func<PrizeType, bool>> predicate2 = GetPredicateEqual<PrizeType>("rewards", (Int16)1000);
Expression<Func<PrizeType, string>> selector2 = GetSelector<PrizeType, string>("name");
var query3 = db.PrizeTypes.Where(predicate2).Select(selector2);
Console.WriteLine(predicate2);
Console.WriteLine(selector2);

//as you can see, query 1 will equal query 2 equal query 3
}
}

public static Expression<Func<TEntity, bool>> GetPredicateEqual<TEntity>(string fieldName, object fieldValue) where TEntity : class {
ParameterExpression m = Expression.Parameter(typeof(TEntity), "t");
var p = m.Type.GetProperty(fieldName);
BinaryExpression body = Expression.Equal(
Expression.Property(m, fieldName),
Expression.Constant(fieldValue, p.PropertyType)
);
return Expression.Lambda<Func<TEntity, bool>>(body, m);
}

public static Expression<Func<T, TReturn>> GetSelector<T, TReturn>(string fieldName)
where T : class
where TReturn : class {
var t = typeof(TReturn);
ParameterExpression p = Expression.Parameter(typeof(T), "t");
var body = Expression.Property(p, fieldName);
return Expression.Lambda<Func<T, TReturn>>(body, new ParameterExpression[] { p });
}

关于c# - 将 Select 方法用于动态查询和表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14741894/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com