@@ -72,7 +72,7 @@ private LambdaToDbExpressionVisitor(DynamicFilterDefinition filter, DbExpression
72
72
_Filter = filter ;
73
73
_Binding = binding ;
74
74
_DbContext = dbContext ;
75
- _ObjectContext = ( ( IObjectContextAdapter ) dbContext ) . ObjectContext ;
75
+ _ObjectContext = ( ( IObjectContextAdapter ) dbContext ) . ObjectContext ;
76
76
_DataSpace = dataSpace ;
77
77
}
78
78
@@ -148,8 +148,8 @@ protected override Expression VisitBinary(BinaryExpression node)
148
148
149
149
case ExpressionType . Coalesce :
150
150
// EF does not expose the "coalesce" function. So best we can do is a case statement. Issue #77.
151
- var whenExpressions = new List < DbExpression > ( ) { DbExpressionBuilder . IsNull ( leftExpression ) } ;
152
- var thenExpressions = new List < DbExpression > ( ) { rightExpression } ;
151
+ var whenExpressions = new List < DbExpression > ( ) { DbExpressionBuilder . IsNull ( leftExpression ) } ;
152
+ var thenExpressions = new List < DbExpression > ( ) { rightExpression } ;
153
153
dbExpression = DbExpressionBuilder . Case ( whenExpressions , thenExpressions , leftExpression ) ;
154
154
break ;
155
155
@@ -217,25 +217,25 @@ protected override Expression VisitConstant(ConstantExpression node)
217
217
}
218
218
219
219
if ( type == typeof ( byte [ ] ) )
220
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromBinary ( ( byte [ ] ) node . Value ) ) ;
220
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromBinary ( ( byte [ ] ) node . Value ) ) ;
221
221
else if ( type == typeof ( bool ) )
222
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromBoolean ( ( bool ? ) node . Value ) ) ;
222
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromBoolean ( ( bool ? ) node . Value ) ) ;
223
223
else if ( type == typeof ( byte ) )
224
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromByte ( ( byte ? ) node . Value ) ) ;
224
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromByte ( ( byte ? ) node . Value ) ) ;
225
225
else if ( type == typeof ( DateTime ) )
226
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromDateTime ( ( DateTime ? ) node . Value ) ) ;
226
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromDateTime ( ( DateTime ? ) node . Value ) ) ;
227
227
else if ( type == typeof ( DateTimeOffset ) )
228
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromDateTimeOffset ( ( DateTimeOffset ? ) node . Value ) ) ;
228
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromDateTimeOffset ( ( DateTimeOffset ? ) node . Value ) ) ;
229
229
else if ( type == typeof ( decimal ) )
230
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromDecimal ( ( decimal ? ) node . Value ) ) ;
230
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromDecimal ( ( decimal ? ) node . Value ) ) ;
231
231
else if ( type == typeof ( double ) )
232
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromDouble ( ( double ? ) node . Value ) ) ;
232
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromDouble ( ( double ? ) node . Value ) ) ;
233
233
else if ( type == typeof ( Guid ) )
234
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromGuid ( ( Guid ? ) node . Value ) ) ;
234
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromGuid ( ( Guid ? ) node . Value ) ) ;
235
235
else if ( type == typeof ( Int16 ) )
236
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt16 ( ( Int16 ? ) node . Value ) ) ;
236
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt16 ( ( Int16 ? ) node . Value ) ) ;
237
237
else if ( type == typeof ( Int32 ) )
238
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt32 ( ( Int32 ? ) node . Value ) ) ;
238
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt32 ( ( Int32 ? ) node . Value ) ) ;
239
239
else if ( type . IsEnum )
240
240
{
241
241
if ( _DataSpace == DataSpace . CSpace )
@@ -244,14 +244,14 @@ protected override Expression VisitConstant(ConstantExpression node)
244
244
MapExpressionToDbExpression ( expression , DbExpressionBuilder . Constant ( typeUsage , node . Value ) ) ;
245
245
}
246
246
else
247
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt32 ( ( Int32 ) node . Value ) ) ;
247
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt32 ( ( Int32 ) node . Value ) ) ;
248
248
}
249
249
else if ( type == typeof ( Int64 ) )
250
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt64 ( ( Int64 ? ) node . Value ) ) ;
250
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromInt64 ( ( Int64 ? ) node . Value ) ) ;
251
251
else if ( type == typeof ( float ) )
252
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromSingle ( ( float ? ) node . Value ) ) ;
252
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromSingle ( ( float ? ) node . Value ) ) ;
253
253
else if ( type == typeof ( string ) )
254
- MapExpressionToDbExpression ( expression , DbConstantExpression . FromString ( ( string ) node . Value ) ) ;
254
+ MapExpressionToDbExpression ( expression , DbConstantExpression . FromString ( ( string ) node . Value ) ) ;
255
255
else
256
256
throw new NotImplementedException ( string . Format ( "Unhandled Type of {0} for Constant value {1} in LambdaToDbExpressionVisitor.VisitConstant" , node . Type . Name , node . Value ?? "null" ) ) ;
257
257
@@ -276,20 +276,20 @@ protected override Expression VisitMember(MemberExpression node)
276
276
// If the value should change or be re-evaluated each time the query is executed, it should
277
277
// be made a parameter of the filter!
278
278
// See https://github.com/jcachat/EntityFramework.DynamicFilters/issues/109
279
- if ( ( node . Expression is ConstantExpression ) || // class field/property
280
- ( ( node . Expression == null ) && ( node . NodeType == ExpressionType . MemberAccess ) ) ) // static field/property
279
+ if ( ( node . Expression is ConstantExpression ) || // class field/property
280
+ ( ( node . Expression == null ) && ( node . NodeType == ExpressionType . MemberAccess ) ) ) // static field/property
281
281
{
282
282
// Class fields & properties must reference the container (the class instance that contains the field/property)
283
- object container = ( node . Expression != null ) ? ( ( ConstantExpression ) node . Expression ) . Value : null ;
283
+ object container = ( node . Expression != null ) ? ( ( ConstantExpression ) node . Expression ) . Value : null ;
284
284
285
- if ( node . Member is FieldInfo ) // regular field property (not a get accessor)
285
+ if ( node . Member is FieldInfo ) // regular field property (not a get accessor)
286
286
{
287
- var value = ( ( FieldInfo ) node . Member ) . GetValue ( container ) ;
287
+ var value = ( ( FieldInfo ) node . Member ) . GetValue ( container ) ;
288
288
return VisitConstant ( Expression . Constant ( value ) ) ;
289
289
}
290
- else if ( node . Member is PropertyInfo ) // get accessor
290
+ else if ( node . Member is PropertyInfo ) // get accessor
291
291
{
292
- object value = ( ( PropertyInfo ) node . Member ) . GetValue ( container , null ) ;
292
+ object value = ( ( PropertyInfo ) node . Member ) . GetValue ( container , null ) ;
293
293
return VisitConstant ( Expression . Constant ( value ) ) ;
294
294
}
295
295
else
@@ -400,10 +400,10 @@ protected override Expression VisitParameter(ParameterExpression node)
400
400
var expression = base . VisitParameter ( node ) ;
401
401
402
402
if ( node . Type . IsClass || node . Type . IsInterface )
403
- return expression ; // Ignore class or interface param
403
+ return expression ; // Ignore class or interface param
404
404
405
405
if ( _Parameters . ContainsKey ( node . Name ) )
406
- return expression ; // Already created sql parameter for this node.Name
406
+ return expression ; // Already created sql parameter for this node.Name
407
407
408
408
// Create a new DbParameterReferenceExpression for this parameter.
409
409
var param = CreateParameter ( node . Name , node . Type ) ;
@@ -482,7 +482,6 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
482
482
#if ( DEBUG_VISITS )
483
483
System . Diagnostics . Debug . Print ( "VisitMethodCall: {0}" , node ) ;
484
484
#endif
485
-
486
485
// Do not call base.VisitMethodCall(node) here because of the method that is being
487
486
// called has a lambdas as an argument, we need to handle it differently. If we call the base,
488
487
// the visits that we do will be against the current binding - not the source of the method call.
@@ -506,6 +505,12 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
506
505
case "All" :
507
506
expression = MapAnyOrAllExpression ( node ) ;
508
507
break ;
508
+ case "ToLower" :
509
+ expression = MapSimpleExpression ( node , EdmFunctions . ToLower ) ;
510
+ break ;
511
+ case "ToUpper" :
512
+ expression = MapSimpleExpression ( node , EdmFunctions . ToUpper ) ;
513
+ break ;
509
514
default :
510
515
// Anything else is invoked and handled as a constant. This allows us to handle user-defined methods.
511
516
// If this evaluates to something that is not a constant, it will throw an exception...which is what we used to do anyway.
@@ -520,7 +525,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
520
525
521
526
return expression ;
522
527
}
523
-
528
+
524
529
private Expression MapEnumerableContainsExpression ( MethodCallExpression node )
525
530
{
526
531
var expression = base . VisitMethodCall ( node ) as MethodCallExpression ;
@@ -536,10 +541,10 @@ private Expression MapEnumerableContainsExpression(MethodCallExpression node)
536
541
if ( ( expression . Arguments . Count > 1 ) && ( expression . Object == null ) )
537
542
collectionObjExp = expression . Arguments [ 0 ] as ParameterExpression ;
538
543
if ( collectionObjExp != null )
539
- argExpression = GetDbExpressionForExpression ( expression . Arguments [ 1 ] ) ; // IEnumerable
544
+ argExpression = GetDbExpressionForExpression ( expression . Arguments [ 1 ] ) ; // IEnumerable
540
545
else
541
546
{
542
- argExpression = GetDbExpressionForExpression ( expression . Arguments [ 0 ] ) ; // List, IList, ICollection
547
+ argExpression = GetDbExpressionForExpression ( expression . Arguments [ 0 ] ) ; // List, IList, ICollection
543
548
collectionObjExp = expression . Object as ParameterExpression ;
544
549
}
545
550
@@ -572,13 +577,13 @@ private Expression MapEnumerableContainsExpression(MethodCallExpression node)
572
577
// Find all of the constant & parameter expressions.
573
578
var constantExpressionList = listExpression . Initializers
574
579
. Select ( i => i . Arguments . FirstOrDefault ( ) as ConstantExpression )
575
- . Where ( c => ( c != null ) && ( c . Value != null ) ) // null not supported - can only use DbConstant in "In" expression
580
+ . Where ( c => ( c != null ) && ( c . Value != null ) ) // null not supported - can only use DbConstant in "In" expression
576
581
. Select ( c => CreateConstantExpression ( c . Value ) )
577
582
. ToList ( ) ;
578
583
constantExpressionList . AddRange ( listExpression . Initializers
579
584
. Select ( i => i . Arguments . FirstOrDefault ( ) as UnaryExpression )
580
585
. Where ( c => ( c != null ) && ( c . Operand is ConstantExpression ) )
581
- . Select ( c => CreateConstantExpression ( ( ( ConstantExpression ) c . Operand ) . Value ) ) ) ;
586
+ . Select ( c => CreateConstantExpression ( ( ( ConstantExpression ) c . Operand ) . Value ) ) ) ;
582
587
var parameterExpressionList = listExpression . Initializers
583
588
. Select ( i => i . Arguments . FirstOrDefault ( ) as ParameterExpression )
584
589
. Where ( c => c != null )
@@ -631,6 +636,16 @@ private bool SupportsIn()
631
636
return ! entityConnection . StoreConnection . GetType ( ) . FullName . Contains ( "Oracle" ) ;
632
637
}
633
638
639
+ private Expression MapSimpleExpression ( MethodCallExpression node , Func < DbExpression , DbFunctionExpression > dbExpressionFactory )
640
+ {
641
+ var expression = base . VisitMethodCall ( node ) as MethodCallExpression ;
642
+
643
+ DbExpression srcExpression = GetDbExpressionForExpression ( expression . Object ) ;
644
+ var dbExpression = dbExpressionFactory ( srcExpression ) ;
645
+ MapExpressionToDbExpression ( expression , dbExpression ) ;
646
+ return expression ;
647
+ }
648
+
634
649
private Expression MapStringLikeExpression ( MethodCallExpression node , bool matchStart , bool matchEnd )
635
650
{
636
651
var expression = base . VisitMethodCall ( node ) as MethodCallExpression ;
0 commit comments