Corey_72

Creating a GroupJoin expression tree

Jul 20th, 2014
222
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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×