使用SelectMany将集合选择器作为Lambda表达式

时间:2015-12-04 12:31:46

标签: c# expression

通过交叉连接组合可枚举和可查询可以使用SelectMany在Linq中编写:

 SomeClass[] AnArray = new SomeClass[] {
   new SomeClass { ... },
   ....
 };

 IQueryable<SomeClass> Outer = AnArray.AsQueryable();
 IQueryable<SomeEntity> Inner = <DbConext>.SomeEntity;

 var Crossed = Outer.SelectMany(
   x => Inner,
   (outer, inner) => new { Outer = outer, Inner = inner }
 );

不确定如何使用表达式树创建集合选择器?

 // Collection Selector
 var OuterAsX = Expression.Parameter(
   Outer.ElementType,
   "x"
 );

 var CollectionSelector = Expression.Lambda(
   ? // <- Some sort of Member Access on Inner
   OuterAsX
 );

 ....

 MethodInfo SelectMethod = (typeof(Queryable))
   .GetMethods()
   .Where(
     method => method.Name == "SelectMany"
       && method.IsGenericMethod
       && method.GetParameters().Length == 3
   )
   .OrderBy(x => x.ToString().Length)
   .First()
   .MakeGenericMethod(
     Outer.ElementType,
     Inner.ElementType,
     ResultType
   );

   IQueryable Query = Inner.Provider.CreateQuery(
     Expression.Call(
       null,
       SelectMethod,
       Outer.Expression,
       CollectionSelector,
       ResultSelector
     )
   );

查看来自Linq的Expression(即Crossed变量),它定义了一个围绕类的Constant,它有两个字段,其中一个是Entity(即Inner),构成一个成员访问表达式:

 Operand    {x => value(Charting.Tests.Engine.GraphTest+<>c__DisplayClass33_0).Inner}
 DebugView  ".Constant<Charting.Tests.Engine.GraphTest+<>c__DisplayClass33_0>(Charting.Tests.Engine.GraphTest+<>c__DisplayClass33_0).Inner"

0 个答案:

没有答案