@@ -56,10 +56,8 @@ open System.Reflection
56
56
/// )
57
57
/// </code></example>
58
58
[<Struct>]
59
- type ObjectListFilterLinqOptions < 'T , 'D > (
60
- [<Optional>] compareDiscriminator : Expression< Func< 'T, 'D, bool>> | null ,
61
- [<Optional>] getDiscriminatorValue : ( Type -> 'D) | null
62
- ) =
59
+ type ObjectListFilterLinqOptions < 'T , 'D >
60
+ ([< Optional>] compareDiscriminator : Expression< Func< 'T, 'D, bool>> | null , [< Optional>] getDiscriminatorValue : ( Type -> 'D) | null ) =
63
61
64
62
member _.CompareDiscriminator = compareDiscriminator |> ValueOption.ofObj
65
63
member _.GetDiscriminatorValue = getDiscriminatorValue |> ValueOption.ofObj
@@ -69,13 +67,16 @@ type ObjectListFilterLinqOptions<'T, 'D> (
69
67
static member GetCompareDiscriminator ( getDiscriminatorValue : Expression < Func < 'T , 'D >>) =
70
68
let tParam = Expression.Parameter ( typeof< 'T>, " x" )
71
69
let dParam = Expression.Parameter ( typeof< 'D>, " d" )
72
- let body = Expression.Equal( Expression.Invoke( getDiscriminatorValue, tParam), dParam)
70
+ let body = Expression.Equal ( Expression.Invoke ( getDiscriminatorValue, tParam), dParam)
73
71
Expression.Lambda< Func< 'T, 'D, bool>> ( body, tParam, dParam)
74
72
75
- new ( getDiscriminator : Expression < Func < 'T , 'D >>) = ObjectListFilterLinqOptions< 'T, 'D> ( ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, null )
73
+ new ( getDiscriminator : Expression < Func < 'T , 'D >>) =
74
+ ObjectListFilterLinqOptions< 'T, 'D> ( ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, null )
76
75
new ( compareDiscriminator : Expression < Func < 'T , 'D , bool >>) = ObjectListFilterLinqOptions< 'T, 'D> ( compareDiscriminator, null )
77
- new ( getDiscriminatorValue : Type -> 'D ) = ObjectListFilterLinqOptions< 'T, 'D> ( compareDiscriminator = null , getDiscriminatorValue = getDiscriminatorValue)
78
- new ( getDiscriminator : Expression < Func < 'T , 'D >>, getDiscriminatorValue : Type -> 'D ) = ObjectListFilterLinqOptions< 'T, 'D> ( ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, getDiscriminatorValue)
76
+ new ( getDiscriminatorValue : Type -> 'D ) =
77
+ ObjectListFilterLinqOptions< 'T, 'D> ( compareDiscriminator = null , getDiscriminatorValue = getDiscriminatorValue)
78
+ new ( getDiscriminator : Expression < Func < 'T , 'D >>, getDiscriminatorValue : Type -> 'D ) =
79
+ ObjectListFilterLinqOptions< 'T, 'D> ( ObjectListFilterLinqOptions.GetCompareDiscriminator getDiscriminator, getDiscriminatorValue)
79
80
80
81
/// Contains tooling for working with ObjectListFilter.
81
82
module ObjectListFilter =
@@ -128,15 +129,25 @@ module ObjectListFilter =
128
129
let private StringEndsWithMethod = typeof< string>. GetMethod ( " EndsWith" , [| typeof< string> |])
129
130
let private StringContainsMethod = typeof< string>. GetMethod ( " Contains" , [| typeof< string> |])
130
131
let private getEnumerableContainsMethod ( memberType : Type ) =
131
- match typeof< Enumerable>. GetMethods( BindingFlags.Static ||| BindingFlags.Public) .FirstOrDefault( fun m -> m.Name = " Contains" && m.GetParameters() .Length = 2 ) with
132
+ match
133
+ typeof< Enumerable>
134
+ .GetMethods( BindingFlags.Static ||| BindingFlags.Public)
135
+ .FirstOrDefault ( fun m -> m.Name = " Contains" && m.GetParameters() .Length = 2 )
136
+ with
132
137
| null -> raise ( MissingMemberException " Static 'Contains' method with 2 parameters not found on 'Enumerable' class" )
133
138
| containsGenericStaticMethod ->
134
- if memberType.IsGenericType && memberType.GenericTypeArguments.Length = 1 then
135
- containsGenericStaticMethod.MakeGenericMethod( memberType.GenericTypeArguments)
139
+ if
140
+ memberType.IsGenericType
141
+ && memberType.GenericTypeArguments.Length = 1
142
+ then
143
+ containsGenericStaticMethod.MakeGenericMethod ( memberType.GenericTypeArguments)
136
144
else
137
- let ienumerable = memberType.GetInterfaces() .First( fun i -> i.FullName.StartsWith " System.Collections.Generic.IEnumerable`1" )
138
- containsGenericStaticMethod.MakeGenericMethod([| ienumerable.GenericTypeArguments[ 0 ] |])
139
-
145
+ let ienumerable =
146
+ memberType
147
+ .GetInterfaces()
148
+ .First ( fun i -> i.FullName.StartsWith " System.Collections.Generic.IEnumerable`1" )
149
+ containsGenericStaticMethod.MakeGenericMethod ([| ienumerable.GenericTypeArguments[ 0 ] |])
150
+
140
151
let getField ( param : ParameterExpression ) fieldName = Expression.PropertyOrField ( param, fieldName)
141
152
142
153
[<Struct>]
@@ -158,25 +169,38 @@ module ObjectListFilter =
158
169
| Equals f -> Expression.Equal ( Expression.PropertyOrField ( param, f.FieldName), Expression.Constant ( f.Value))
159
170
| GreaterThan f -> Expression.GreaterThan ( Expression.PropertyOrField ( param, f.FieldName), Expression.Constant ( f.Value))
160
171
| LessThan f -> Expression.LessThan ( Expression.PropertyOrField ( param, f.FieldName), Expression.Constant ( f.Value))
161
- | StartsWith f ->
162
- Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), StringStartsWithMethod, Expression.Constant ( f.Value))
163
- | EndsWith f ->
164
- Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), StringEndsWithMethod, Expression.Constant ( f.Value))
172
+ | StartsWith f -> Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), StringStartsWithMethod, Expression.Constant ( f.Value))
173
+ | EndsWith f -> Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), StringEndsWithMethod, Expression.Constant ( f.Value))
165
174
| Contains f ->
166
175
let ``member`` = Expression.PropertyOrField ( param, f.FieldName)
167
- let isEnumerable ( memberType : Type ) =
168
- not ( Type.(=)( memberType, typeof< string>))
169
- && typeof< System.Collections.IEnumerable>. IsAssignableFrom( memberType)
170
- && memberType.GetInterfaces() .Any( fun i -> i.FullName.StartsWith " System.Collections.Generic.IEnumerable`1" )
171
- match `` member `` .Member with
176
+ let isEnumerable ( memberType : Type ) =
177
+ not ( Type.(=) ( memberType, typeof< string>))
178
+ && typeof< System.Collections.IEnumerable>. IsAssignableFrom ( memberType)
179
+ && memberType
180
+ .GetInterfaces()
181
+ .Any ( fun i -> i.FullName.StartsWith " System.Collections.Generic.IEnumerable`1" )
182
+ match `` member `` .Member with
172
183
| :? PropertyInfo as prop when prop.PropertyType |> isEnumerable ->
173
- match prop.PropertyType.GetMethods( BindingFlags.Instance ||| BindingFlags.Public) .FirstOrDefault( fun m -> m.Name = " Contains" && m.GetParameters() .Length = 1 ) with
174
- | null -> Expression.Call ( getEnumerableContainsMethod prop.PropertyType, Expression.PropertyOrField ( param, f.FieldName), Expression.Constant ( f.Value))
175
- | instanceContainsMethod -> Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), instanceContainsMethod, Expression.Constant ( f.Value))
184
+ match
185
+ prop.PropertyType
186
+ .GetMethods( BindingFlags.Instance ||| BindingFlags.Public)
187
+ .FirstOrDefault ( fun m -> m.Name = " Contains" && m.GetParameters() .Length = 1 )
188
+ with
189
+ | null ->
190
+ Expression.Call (
191
+ getEnumerableContainsMethod prop.PropertyType,
192
+ Expression.PropertyOrField ( param, f.FieldName),
193
+ Expression.Constant ( f.Value)
194
+ )
195
+ | instanceContainsMethod ->
196
+ Expression.Call ( Expression.PropertyOrField ( param, f.FieldName), instanceContainsMethod, Expression.Constant ( f.Value))
176
197
| :? FieldInfo as field when field.FieldType |> isEnumerable ->
177
- Expression.Call ( getEnumerableContainsMethod field.FieldType, Expression.PropertyOrField ( param, f.FieldName), Expression.Constant ( f.Value))
178
- | _ ->
179
- Expression.Call ( `` member `` , StringContainsMethod, Expression.Constant ( f.Value))
198
+ Expression.Call (
199
+ getEnumerableContainsMethod field.FieldType,
200
+ Expression.PropertyOrField ( param, f.FieldName),
201
+ Expression.Constant ( f.Value)
202
+ )
203
+ | _ -> Expression.Call ( `` member `` , StringContainsMethod, Expression.Constant ( f.Value))
180
204
| OfTypes types ->
181
205
types
182
206
|> Seq.map ( fun t -> buildTypeDiscriminatorCheck param t)
@@ -198,23 +222,26 @@ module ObjectListFilter =
198
222
Expression.PropertyOrField ( param, " __typename" ),
199
223
// Default discriminator value
200
224
Expression.Constant ( t.FullName)
201
- ) :> Expression
225
+ )
226
+ :> Expression
202
227
| ValueSome discExpr, ValueNone ->
203
228
Expression.Invoke (
204
229
// Provided discriminator comparison
205
230
discExpr,
206
231
param,
207
232
// Default discriminator value gathered from type
208
- Expression.Constant( t.FullName)
209
- ) :> Expression
233
+ Expression.Constant ( t.FullName)
234
+ )
235
+ :> Expression
210
236
| ValueNone, ValueSome discValueFn ->
211
237
let discriminatorValue = discValueFn t
212
238
Expression.Equal (
213
239
// Default discriminator property
214
240
Expression.PropertyOrField ( param, " __typename" ),
215
241
// Provided discriminator value gathered from type
216
242
Expression.Constant ( discriminatorValue)
217
- ) :> Expression
243
+ )
244
+ :> Expression
218
245
| ValueSome discExpr, ValueSome discValueFn ->
219
246
let discriminatorValue = discValueFn t
220
247
Expression.Invoke (
@@ -243,5 +270,4 @@ module ObjectListFilterExtensions =
243
270
244
271
type IQueryable < 'T > with
245
272
246
- member inline query.Apply ( filter : ObjectListFilter , [<Optional>] options : ObjectListFilterLinqOptions < 'T , 'D >) =
247
- apply options filter query
273
+ member inline query.Apply ( filter : ObjectListFilter , [<Optional>] options : ObjectListFilterLinqOptions < 'T , 'D >) = apply options filter query
0 commit comments