好的,我承认我还没有完全理解lambda表达式和LINQ表达式树;我所做的很多事情都是剪切和粘贴,看看哪些有效。我查看了很多文档,但我仍然没有找到我的“恍然大悟”的时刻。
话虽如此...
我试图动态添加一个GroupBy表达式到我的Linq表达式中。我遵循了这里的问题: Need help creating Linq.Expression to Enumerable.GroupBy 并尝试实现我在那里看到的内容。
首先,我有用于我的数据库的实体类和一个名为ObjCurLocViewNormalized的表。
我有一个方法来进行初始调用,
所有的代码都编译成功了,但是运行时出现了错误:。这个错误该怎么解决呢?
我正在复制和调整我在动态添加Where子句到表达式方面的成功工作中使用的代码。所以我有点盲目地尝试。
如果有人能帮忙解决这个问题,显然发布完整的可工作代码并为我思考所有内容将是很棒的 :), 但如果你只能说明这是错误的原因,或者如何理解这些概念,那就太好了。如果你能指出可以真正帮助我填补lambda表达式基础和构建动态表达式树之间差距的文档,那就太好了。我的知识中存在明显的漏洞,但我认为这些信息可能对其他人有用。
谢谢大家花时间阅读,当然,如果我在其他地方找到答案,我会在这里发布的。
再次感谢。
唐
话虽如此...
我试图动态添加一个GroupBy表达式到我的Linq表达式中。我遵循了这里的问题: Need help creating Linq.Expression to Enumerable.GroupBy 并尝试实现我在那里看到的内容。
首先,我有用于我的数据库的实体类和一个名为ObjCurLocViewNormalized的表。
我有一个方法来进行初始调用,
public IQueryable<ObjCurLocViewNormalized> getLocations()
{
IQueryable<ObjCurLocViewNormalized> res = (from loc in tms.ObjCurLocViewNormalized
select loc);
return res;
}
所以我可以调用:
IQueryable<MetAmericanLinqDataModel.ObjCurLocViewNormalized> locations = american.getLocations();
到目前为止还没有问题。
现在,我想通过以下方式对任意列进行分组:
var grouped = locations.addGroupBy(childLocationFieldName);
现在,我有一个方法:
static public System.Linq.IQueryable<System.Linq.IGrouping<string, TResult>> addGroupBy<TResult>(this IQueryable<TResult> query, string columnName)
{
var providerType = query.Provider.GetType();
// Find the specific type parameter (the T in IQueryable<T>)
var iqueryableT = providerType.FindInterfaces((ty, obj) => ty.IsGenericType && ty.GetGenericTypeDefinition() == typeof(IQueryable<>), null).FirstOrDefault();
var tableType = iqueryableT.GetGenericArguments()[0];
var tableName = tableType.Name;
var data = Expression.Parameter(iqueryableT, "query");
var arg = Expression.Parameter(tableType, tableName);
var nameProperty = Expression.PropertyOrField(arg, columnName);
var lambda = Expression.Lambda<Func<TResult, string>>(nameProperty, arg);
var expression = Expression.Call(typeof(Enumerable),
"GroupBy",
new Type[] { tableType, typeof(string) },
data,
lambda);
var predicate = Expression.Lambda<Func<TResult, String>>(expression, arg); // this is the line that produces the error I describe below
var result = query.GroupBy(predicate).AsQueryable();
return result;
}
所有的代码都编译成功了,但是运行时出现了错误:。这个错误该怎么解决呢?
System.ArgumentException: Expression of type 'System.Collections.Generic.IEnumerable`1[System.Linq.IGrouping`2[System.String,MetAmericanLinqDataModel.ObjCurLocViewNormalized]]' cannot be used for return type 'System.String'
错误来自于这一行:
var predicate = Expression.Lambda<Func<TResult, String>>(expression, arg);
我正在复制和调整我在动态添加Where子句到表达式方面的成功工作中使用的代码。所以我有点盲目地尝试。
如果有人能帮忙解决这个问题,显然发布完整的可工作代码并为我思考所有内容将是很棒的 :), 但如果你只能说明这是错误的原因,或者如何理解这些概念,那就太好了。如果你能指出可以真正帮助我填补lambda表达式基础和构建动态表达式树之间差距的文档,那就太好了。我的知识中存在明显的漏洞,但我认为这些信息可能对其他人有用。
谢谢大家花时间阅读,当然,如果我在其他地方找到答案,我会在这里发布的。
再次感谢。
唐
predicate
行使用了Func<TResult, string>
?你的表达式返回的是一个IGrouping
,而不是一个string
。 - Kirk Woll.GroupBy
的调用和传递给它的lambda谓词。目前没有时间进一步回答,但如果一个小时后这个问题仍未得到解答,我会更加彻底地尝试回答。 - Kirk Woll