Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Having trouble building left outer join with multiple conditions using Dynamic Linq

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 35
    Answer it

    I am trying to build Dynamic Left outer join Linq query.

     

    I took help from StackOverflow page titled "How do I do a left outer join with Dynamic Linq?"

     

    I am getting the following error in "SelectMany".

     

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

     

    Code I have is :

    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 which supports table-column-like data store
    Supports ONLY string-indexed accessors:

     

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

     

    I am calling the GroupJoin like this :

     

     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 executes fine but the problem is with the value for selector parameter of SelectMany. i.e.. "ls.DefaultIfEmpty()"

     

    What should I be passing for selector parameter of SelectMany?

     

 0 Answer(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: