Corey_72

Creating a GroupJoin expression tree

Jul 20th, 2014
215
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. void Main()
  2. {
  3.     var fn = GroupJoinExp<IndexString, IndexNumber, JoinResult>();
  4.    
  5.     Console.WriteLine(fn.ToString());
  6. }
  7.  
  8. // Define other methods and classes here
  9. public Expression<Func<IQueryable<TOuter>, IEnumerable<TInner>, IQueryable<TResult>>> GroupJoinExp<TOuter, TInner, TResult>()
  10. {
  11.     var tOuter = typeof(TOuter);
  12.     var miOuterKey = tOuter.GetMember("index")[0];
  13.     var miOuterValue = tOuter.GetMember("value")[0];
  14.     var tInner = typeof(TInner);
  15.     var miInnerKey = tInner.GetMember("index")[0];
  16.    
  17.     var pOuter = Expression.Parameter(tOuter, "o");
  18.     var pInner = Expression.Parameter(tInner, "i");
  19.    
  20.     var miResStr = typeof(TResult).GetMember("str")[0];
  21.     var miResGrp = typeof(TResult).GetMember("grp")[0];
  22.    
  23.    
  24.     // selector expression:
  25.     var pInnerEnum = Expression.Parameter(typeof(IEnumerable<TInner>), "g");
  26.  
  27.     var meminit =
  28.             Expression.MemberInit(
  29.                 Expression.New(typeof(TResult)),
  30.                 Expression.Bind(miResStr, Expression.MakeMemberAccess(pOuter, miOuterValue)),
  31.                 Expression.Bind(miResGrp, pInnerEnum)
  32.             );
  33.     var selector = Expression.Lambda(meminit, pOuter, pInnerEnum);
  34.    
  35.     // parameters for GroupJoin:
  36.     var gjpOuter = Expression.Parameter(typeof(IQueryable<TOuter>), "outer");
  37.     var gjpInner = Expression.Parameter(typeof(IEnumerable<TInner>), "inner");
  38.     var gjpOuterKeySelector = Expression.Lambda(Expression.MakeMemberAccess(pOuter, miOuterKey), pOuter);
  39.     var gjpInnerKeySelector = Expression.Lambda(Expression.MakeMemberAccess(pInner, miInnerKey), pInner);
  40.     var gjpSelector = selector;
  41.    
  42.     // GroupJoin expression
  43.     var fnGrpJn = Expression.Call(typeof(Queryable), "GroupJoin", new Type [] { tOuter, tInner, typeof(Int32), typeof(TResult) },
  44.         gjpOuter,
  45.         gjpInner,
  46.         gjpOuterKeySelector,
  47.         gjpInnerKeySelector,
  48.         gjpSelector
  49.     );
  50.    
  51.     var res = (Expression<Func<IQueryable<TOuter>, IEnumerable<TInner>, IQueryable<TResult>>>) Expression.Lambda(fnGrpJn, gjpOuter, gjpInner);
  52.     return res;    
  53. }
  54.  
  55. public class IndexString
  56. {
  57.     public int index;
  58.     public string value;
  59. }
  60.  
  61. public class IndexNumber
  62. {
  63.     public int index;
  64.     public double dbl;
  65. }
  66.  
  67. public class JoinResult
  68. {
  69.     public string str;
  70.     public IEnumerable<IndexNumber> grp;
  71. }
RAW Paste Data