left outer join with multiple conditions using Dynamic Linq

c# dynamic-linq linq

Question

I'm attempting to constructDynamic Left outer join Linq request

I used the How can I use Dynamic Linq to do a left outer join?.

I'm encountering the next error"SelectMany" .

 System.Linq.Dynamic.ParseException: 'No property or field 'ls' exists in type 'DataStore''

I have this code:

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 is a class that provides data stores with table-like columns.
Supports ONLY accessors that are string-indexed:

ds["Name"] = "John"
    new DataStore("Employee"){ ["Name"] = "John"} 

I'm referring to the GroupJoin as follows:

 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)");

The GroupJoin runs without issue, however the value forselector element ofSelectMany . i.e.."ls.DefaultIfEmpty()"

What am I supposed to pass for?selector element ofSelectMany ?

1
1
8/23/2018 2:21:02 AM

Popular Answer

Have you tried the (.NET Core) version more recent as well, which does supportGroupJoin beyond the box?

Look at this: 16-zzz.

0
9/4/2018 7:15:47 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow