我正在使用Linq-to-Entities,一个查询需要动态加载属性。查询如下所示:
var found = Context.IntegrateViews.GroupBy(x => x.TypeOfBed)
.Select(type => new TypeCounts
{ Name = type.Key, Count = type.Count() }).ToList();
正在运行Group By子句的属性是TypeOfBed。现在我想在不同的属性上运行此查询,例如,下次我要运行它时,让我们说x.TypeOfChair等等。为此,我需要动态地拥有这个属性。
我正在尝试编写一个像这样的表达式构建器。
public Expression<Func<LookupFilterItem>> PropertyLambda(string propertyName)
{
var param = Expression.Parameter(typeof(LookupFilterItem), "lookupItem");
//type of x in above example is LookupFilterItem
var propertyExpression = Expression.Property(param, propertyName);
var returnExpr = Expression.Lambda<Func<LookupFilterItem>>(propertyExpression);
return returnExpr;
//If I Pass string "TypeOfBed" to this method, I am expecting it to return something like
// lookupItem => lookupItem.TypeOfBed
}
我打算像这样使用它:
var found = Context.IntegrateViews.GroupBy(PropertyLambda("TypeOfBed"))
.Select(type => new TypeCounts
{ Name = type.Key, Count = type.Count() }).ToList();
但这不起作用,我收到一个编译时错误,上面写着:
错误CS0411:方法的类型参数 &#39; System.Linq.Queryable.GroupBy(System.Linq.IQueryable, System.Linq.Expressions.Expression&GT;)&#39;不能 从用法推断。尝试指定类型参数 明确。
我在这里做错了什么?
答案 0 :(得分:3)
尚未测试,但以下扩展方法如何?
private static Expression<Func<T, K>> MakeExpr<T, K>(this IQueryable<T> source, string property)
{
var type = typeof(T);
var arg = Expression.Parameter(type, "x");
var expr = Expression.Property(arg, property);
var lambda = Expression.Lambda<Func<T, K>>(expr, arg);
return lambda;
}
public static IQueryable<IGrouping<K, T>> GroupBy<T, K>(this IQueryable<T> source, string property)
{
return source.GroupBy(MakeExpr<T, K>(source, property));
}
答案 1 :(得分:1)
这似乎是一个语法问题。试试这个:
public Expression<Func<LookupFilterItem, string>> PropertyLambda(string propertyName)
{
var param = Expression.Parameter(typeof(LookupFilterItem), "lookupItem");
var propertyExpression = Expression.Property(param, propertyName);
var returnExpr = Expression.Lambda<Func<LookupFilterItem, string>>(propertyExpression, param);
return returnExpr;
}
用法:
var found = Context.IntegrateViews.GroupBy(PropertyLambda("TypeOfBed").Compile())
.Select(type => new TypeCounts
{ Name = type.Key, Count = type.Count() }).ToList();
答案 2 :(得分:0)
另一种选择是使用LINQ Dynamic Query Library:
using System.Linq.Dynamic;
var found = Context.IntegrateViews.AsQueryable().GroupBy("new(TypeOfBed)", "it")
.Select(new (Key.TypeOfBed as Name, Count() as Count)).ToList();