0
public class Source
{
    public int SourceID;
    public int? SecurityId;
    public int? CUSIP;
    public string Text;
}

public class Destination
{
    public int DestinationID;
    public int? SecurityId;
    public int? CUSIP;
    public string Text;
}

IQueryable listleftJn = 
    listOfSources
    .AsQueryable()
    .GroupJoin(
        listOfDestinations.AsQueryable(),
        "new (outer.SecurityId as SecurityId, outer.CUSIP as CUSIP)",
        "new (inner.SecurityId as SecurityId, inner.CUSIP as CUSIP)",
        "new (outer as sources, group as destinations)")
    .SelectMany(
        "destinations",
        "new(outer as sources, inner as destinations)");

How to shape the result of dynamic IQueryable listleftJn and Map it to a Class Type. So that I can Use the Mapped Class for further use.

Yacoub Massad
  • 26,006
  • 2
  • 31
  • 56
Ashutosh
  • 53
  • 6
  • Are you using a custom `GroupJoin` method? – Yacoub Massad Jan 20 '16 at 17:32
  • Yes I am using Custom GroupJoin method. – Ashutosh Jan 20 '16 at 18:19
  • There are 2 classes involved in the join, what is the expected class type of the result? i.e. `IQueryable> result = [we need to figure out]`, what should be `?` – Ivan Stoev Jan 20 '16 at 18:38
  • IQuerable – Ashutosh Jan 20 '16 at 19:03
  • I need a class which will give the Output of both the joins. The output should be as Source.SourceId, Destination.DestinationID,Source.SecurityId,Destination.SecurityId,Source.CUSIP,Destination.CUSIP,Source.Text,Destination.text. These are all the properties which will be defined in a Class "ResultOfSOurceAndDestination" and I want to map the properties defined in ResultOfSOurceAndDestination to the result of groupjoin IQueryable result. – Ashutosh Jan 20 '16 at 19:10

1 Answers1

2

I believe you can use the approach from my answer to Execution-Deferred IQueryable<T> from Dynamic Linq?

First, add the same helper method from the link

public static class DynamicQueryableEx
{
    public static IQueryable<TResult> Select<TResult>(this IQueryable source, string selector, params object[] values)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (selector == null) throw new ArgumentNullException("selector");
        var dynamicLambda = System.Linq.Dynamic.DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
        var memberInit = dynamicLambda.Body as MemberInitExpression;
        if (memberInit == null) throw new NotSupportedException();
        var resultType = typeof(TResult);
        var bindings = memberInit.Bindings.Cast<MemberAssignment>()
            .Select(mb => Expression.Bind(
                (MemberInfo)resultType.GetProperty(mb.Member.Name) ?? resultType.GetField(mb.Member.Name),
                mb.Expression));
        var body = Expression.MemberInit(Expression.New(resultType), bindings);
        var lambda = Expression.Lambda(body, dynamicLambda.Parameters);
        return source.Provider.CreateQuery<TResult>(
            Expression.Call(
                typeof(Queryable), "Select",
                new Type[] { source.ElementType, lambda.Body.Type },
                source.Expression, Expression.Quote(lambda)));
    }
}

Then you can use something like this

var result = listleftJn.Select<ResultOfSOurceAndDestination>(
    "new (sources.SourceId as SourceId, destinations.DestinationID as DestinationID, sources.SecurityId as SecurityId, etc...)");

Don't forget to use sources and destinations accessors (that you defined inside the SelectMany - "new(outer as sources, inner as destinations)"). I would use in both places source and destination, or shorter s and d, but that's not essential as soon as they match.

UPDATE: There is also a problem in your SelectMany projection.

"new(outer as sources, inner as destinations)"

should be

"new(outer.sources as sources, inner as destinations)"
Community
  • 1
  • 1
Ivan Stoev
  • 159,890
  • 9
  • 211
  • 258