我正在使用LambdaExpression
动态选择列:
var property = "power_usage"; // I set this dynamically.
var entityType = typeof(system_state);
var prop = entityType.GetProperty(property);
var source = Expression.Parameter(entityType, "ss");
var func = typeof(Func<,>);
var genericFunc = func.MakeGenericType(typeof(system_state), prop.PropertyType);
var linqQuery = context.system_state
.Where(ss => ss.time_stamp >= StartDate && ss.time_stamp <= EndDate)
.Select(genericFunc, Expression.PropertyOrField(source, property), source);
变量genericFunc
应该定义delegateType
,但我仍然会遇到此错误。我在做什么错?
我会引用@ivan stoev
问题是需要在编译时知道
TResult
,因此linqQuery
(必须(为IQueryable<string>
或IQueryable<int>
等。无法在运行时解决var
的类型。可以动态发出呼叫Select
,但是您所能获得的只是一个非通用IQueryable
,这并不是那么有用。您可能会查看Dynamiclinq软件包,以查看其如何解决此问题和类似问题。但是,即使有它,与UntypedIQueryable
一起工作也很痛苦。
那么,如果您真的想这样做...最后是您的代码: - (
可以缓存:
private static readonly MethodInfo selectT = (from x in typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static)
where x.Name == nameof(Queryable.Select) && x.IsGenericMethod
let gens = x.GetGenericArguments()
where gens.Length == 2
let pars = x.GetParameters()
where pars.Length == 2 &&
pars[0].ParameterType == typeof(IQueryable<>).MakeGenericType(gens[0]) &&
pars[1].ParameterType == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(gens))
select x).Single();
然后:
var property = "power_usage"; // I set this dynamically.
var entityType = typeof(system_state);
var prop = entityType.GetProperty(property);
var source = Expression.Parameter(entityType, "ss");
var func = typeof(Func<,>);
var genericFunc = func.MakeGenericType(typeof(system_state), prop.PropertyType);
var baseQuery = context.system_state
.Where(ss => ss.time_stamp >= StartDate && ss.time_stamp <= EndDate);
var exp = Expression.Lambda(Expression.Property(source, prop), source);
MethodInfo select = selectT.MakeGenericMethod(entityType, prop.PropertyType);
IQueryable query = (IQueryable)select.Invoke(null, new object[] { baseQuery, exp });
var result = query.Cast<object>().ToArray();
请注意,我正在获得一个非生成IQueryable
...然后我将其元素投放到object
并进行ToArray()
,但是您可以对此做任何想做的事情。在IQueryable
下方将强烈键入,因此它将是IQueryable<int>
或IQueryable<something>
,因此您可以将其施放回"真实"界面(IQueryable<T>
从IQueryable
继承(