@@ -19,11 +19,12 @@ type [<AbstractClass; Sealed>] QueryExtensions =
1919 else base .Visit node }
2020 [<Extension>]
2121 static member Replace ( x : Expression , find , replace ) = QueryExtensions.Replace( find, replace) .Visit( x)
22+ [<Extension>]
23+ static member InlineParam ( f : Expression < Func < 'T , 'I >>, expr ) = f.Body.Replace( f.Parameters[ 0 ], expr)
2224 [<Extension>] // https://stackoverflow.com/a/8829845/11635
2325 static member Compose ( selector : Expression < Func < 'T , 'I >>, projector : Expression < Func < 'I , 'R >>): Expression < Func < 'T , 'R >> =
2426 let param = Expression.Parameter( typeof< 'T>, " x" )
25- let prop = selector.Body.Replace( selector.Parameters[ 0 ], param)
26- let body = projector.Body.Replace( projector.Parameters[ 0 ], prop)
27+ let body = projector.InlineParam( selector.InlineParam param)
2728 Expression.Lambda< Func< 'T, 'R>>( body, param)
2829 [<Extension>]
2930 static member OrderBy ( source : IQueryable < 'T >, indexSelector : Expression < Func < 'T , 'I >>, keySelector : Expression < Func < 'I , 'U >>, descending ) =
@@ -165,16 +166,14 @@ type SnAndSnap() =
165166 dataExpression : Expression < Func < 'U , System.Text.Json.JsonElement >>) =
166167 let param = Expression.Parameter( typeof< 'T>, " x" )
167168 let targetType = typeof< SnAndSnap>
168- let snMember = targetType.GetMember( nameof Unchecked.defaultof< SnAndSnap>. sn)[ 0 ]
169- let formatMember = targetType.GetMember( nameof Unchecked.defaultof< SnAndSnap>. D)[ 0 ]
170- let dataMember = targetType.GetMember( nameof Unchecked.defaultof< SnAndSnap>. d)[ 0 ]
171- Expression.Lambda< Func< 'T, SnAndSnap>>(
169+ let bind ( name , expr ) = Expression.Bind( targetType.GetMember( name)[ 0 ], expr) :> MemberBinding
170+ let body =
172171 Expression.MemberInit(
173172 Expression.New( targetType.GetConstructor [||]),
174- [| Expression.Bind ( snMember , snExpression param) :> MemberBinding
175- Expression.Bind ( formatMember , QueryExtensions .Compose( uExpression , formatExpression) .Body.Replace ( uExpression.Parameters [ 0 ], param))
176- Expression.Bind ( dataMember , uExpression.Compose( dataExpression) .Body.Replace ( uExpression.Parameters [ 0 ], param)) |]),
177- [| param |])
173+ [| bind ( nameof Unchecked.defaultof < SnAndSnap >. sn , snExpression param)
174+ bind ( nameof Unchecked.defaultof < SnAndSnap >. D , uExpression .Compose( formatExpression) .InlineParam ( param))
175+ bind ( nameof Unchecked.defaultof < SnAndSnap >. d , uExpression.Compose( dataExpression) .InlineParam ( param)) |])
176+ Expression.Lambda < Func < 'T , SnAndSnap >>( body , [| param |])
178177
179178/// Represents a query projecting information values from an Index and/or Snapshots with a view to rendering the items and/or a count
180179type Query < 'T , 'M >( inner : Internal.Projection < 'T , 'M >) =
@@ -234,6 +233,7 @@ type IndexContext<'I>(container, categoryName, caseName, log, [<O; D null>]?quer
234233 member val Log = log
235234 member val Description = $" {categoryName}/{caseName}" with get, set
236235 member val Container = container
236+ member val CategoryName = categoryName
237237
238238 /// Helper to make F# consumption code more terse (the F# compiler generates Expression trees only when a function is passed to a `member`)
239239 /// Example: `i.Predicate(fun e -> e.name = name)`
0 commit comments