【发布时间】:2018-08-23 00:03:20
【问题描述】:
我正在尝试构建Dynamic Left outer join Linq 查询。
我得到了How do I do a left outer join with Dynamic Linq?的帮助
我在"SelectMany" 中收到以下错误。
System.Linq.Dynamic.ParseException: 'No property or field 'ls' exists in type 'DataStore''
我的代码是:
public static IQueryable GroupJoin(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values)
{
if (inner == null) throw new ArgumentNullException("inner");
if (outerSelector == null) throw new ArgumentNullException("outerSelector");
if (innerSelector == null) throw new ArgumentNullException("innerSelector");
if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor");
LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values);
Type enumType = typeof(IEnumerable<>).MakeGenericType(inner.AsQueryable().ElementType);
LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values);
ParameterExpression[] parameters = new ParameterExpression[] {
Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(enumType, "inner")};
LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values);
return outer.Provider.CreateQuery(
Expression.Call(
typeof(Queryable), "GroupJoin",
new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type },
outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda)));
}
public static IQueryable SelectMany(this IQueryable source, string selector,string resultsSelector, params object[] values)
{
if (source == null) throw new ArgumentNullException("source");
if (selector == null) throw new ArgumentNullException("selector");
LambdaExpression lambda = DynamicExpression.ParseLambda(
source.ElementType, null, selector, values);
Type inputType = source.Expression.Type.GetGenericArguments()[0];
Type resultType = lambda.Body.Type.GetGenericArguments()[0];
Type enumerableType = typeof(IEnumerable<>).MakeGenericType(resultType);
Type delegateType = typeof(Func<,>).MakeGenericType(inputType, enumerableType);
lambda = Expression.Lambda(delegateType, lambda.Body, lambda.Parameters);
ParameterExpression[] parameters = new ParameterExpression[] {
Expression.Parameter(source.ElementType, "outer"),
Expression.Parameter(resultType, "inner")
};
LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(
parameters, null, resultsSelector, values);
// Create the new query
return source.Provider.CreateQuery(Expression.Call(typeof(Queryable),
"SelectMany", new Type[] {
source.ElementType,
resultType,
resultsSelectorLambda.Body.Type
}, source.Expression, Expression.Quote(lambda),
Expression.Quote(resultsSelectorLambda)));
}
public static object DefaultIfEmpty(this IQueryable source)
{
if (source == null) throw new ArgumentNullException("source");
return source.Provider.Execute(
Expression.Call(
typeof(Queryable), "DefaultIfEmpty",
new Type[] { source.ElementType },
source.Expression));
}
Datastore 是一个支持类表列数据存储的类
仅支持字符串索引的访问器:
ds["Name"] = "John"
new DataStore("Employee"){ ["Name"] = "John"}
我是这样调用 GroupJoin 的:
var qry = otherSource.AsQueryable().GroupJoin(source, "new(it["FirstName"] as key0,it["City"] as key1)", "new(it["FirstName"] as key0,it["City"] as key1)", "new(inner as ls , outer as rs)").SelectMany("ls.DefaultIfEmpty()", "new(inner.ls as l, rs as r)");
GroupJoin 执行良好,但问题在于SelectMany 的selector 参数值。即"ls.DefaultIfEmpty()"
我应该为SelectMany 的selector 参数传递什么?
【问题讨论】:
标签: c# linq dynamic-linq