@@ -240,79 +240,78 @@ private IMongoQuery BuildAnyQuery(MethodCallExpression methodCallExpression)
240
240
241
241
private IMongoQuery BuildArrayLengthQuery ( BinaryExpression binaryExpression )
242
242
{
243
- var leftUnaryExpression = binaryExpression . Left as UnaryExpression ;
244
- if ( leftUnaryExpression != null )
243
+ // the constant could be on either side (but only == and != are supported and they don't need to be flipped)
244
+ var variableExpression = binaryExpression . Left ;
245
+ var constantExpression = binaryExpression . Right as ConstantExpression ;
246
+ if ( constantExpression == null )
247
+ {
248
+ constantExpression = binaryExpression . Left as ConstantExpression ;
249
+ variableExpression = binaryExpression . Right ;
250
+ }
251
+
252
+ if ( constantExpression == null || constantExpression . Type != typeof ( int ) )
245
253
{
246
- if ( leftUnaryExpression . NodeType == ExpressionType . ArrayLength )
254
+ return null ;
255
+ }
256
+
257
+ BsonSerializationInfo serializationInfo = null ;
258
+ var value = ToInt32 ( constantExpression ) ;
259
+
260
+ var unaryExpression = variableExpression as UnaryExpression ;
261
+ if ( unaryExpression != null )
262
+ {
263
+ if ( unaryExpression . NodeType == ExpressionType . ArrayLength )
247
264
{
248
- var memberExpression = leftUnaryExpression . Operand as MemberExpression ;
249
- var valueExpression = binaryExpression . Right as ConstantExpression ;
250
- if ( memberExpression != null && valueExpression != null )
265
+ var memberExpression = unaryExpression . Operand as MemberExpression ;
266
+ if ( memberExpression != null )
251
267
{
252
- var serializationInfo = GetSerializationInfo ( memberExpression ) ;
253
- var value = ( int ) valueExpression . Value ;
254
- if ( binaryExpression . NodeType == ExpressionType . Equal )
255
- {
256
- return Query . Size ( serializationInfo . ElementName , value ) ;
257
- }
258
- else
259
- {
260
- return Query . Not ( serializationInfo . ElementName ) . Size ( value ) ;
261
- }
268
+ serializationInfo = GetSerializationInfo ( memberExpression ) ;
262
269
}
263
270
}
264
271
}
265
272
266
- var leftMemberExpression = binaryExpression . Left as MemberExpression ;
267
- if ( leftMemberExpression != null )
273
+ var countPropertyExpression = variableExpression as MemberExpression ;
274
+ if ( countPropertyExpression != null )
268
275
{
269
- if ( leftMemberExpression . Member . Name == "Count" )
276
+ if ( countPropertyExpression . Member . Name == "Count" )
270
277
{
271
- var memberExpression = leftMemberExpression . Expression as MemberExpression ;
272
- var valueExpression = binaryExpression . Right as ConstantExpression ;
273
- if ( memberExpression != null && valueExpression != null )
278
+ var memberExpression = countPropertyExpression . Expression as MemberExpression ;
279
+ if ( memberExpression != null )
274
280
{
275
- var serializationInfo = GetSerializationInfo ( memberExpression ) ;
276
- var value = ( int ) valueExpression . Value ;
277
- if ( binaryExpression . NodeType == ExpressionType . Equal )
278
- {
279
- return Query . Size ( serializationInfo . ElementName , value ) ;
280
- }
281
- else
282
- {
283
- return Query . Not ( serializationInfo . ElementName ) . Size ( value ) ;
284
- }
281
+ serializationInfo = GetSerializationInfo ( memberExpression ) ;
285
282
}
286
283
}
287
284
}
288
285
289
- var leftMethodCallExpression = binaryExpression . Left as MethodCallExpression ;
290
- if ( leftMethodCallExpression != null )
286
+ var countMethodCallExpression = variableExpression as MethodCallExpression ;
287
+ if ( countMethodCallExpression != null )
291
288
{
292
- if ( leftMethodCallExpression . Method . Name == "Count" )
289
+ if ( countMethodCallExpression . Method . Name == "Count" )
293
290
{
294
- var arguments = leftMethodCallExpression . Arguments . ToArray ( ) ;
291
+ var arguments = countMethodCallExpression . Arguments . ToArray ( ) ;
295
292
if ( arguments . Length == 1 )
296
293
{
297
- var memberExpression = leftMethodCallExpression . Arguments [ 0 ] as MemberExpression ;
298
- var valueExpression = binaryExpression . Right as ConstantExpression ;
299
- if ( memberExpression != null && valueExpression != null )
294
+ var memberExpression = countMethodCallExpression . Arguments [ 0 ] as MemberExpression ;
295
+ if ( memberExpression != null )
300
296
{
301
- var serializationInfo = GetSerializationInfo ( memberExpression ) ;
302
- var value = ( int ) valueExpression . Value ;
303
- if ( binaryExpression . NodeType == ExpressionType . Equal )
304
- {
305
- return Query . Size ( serializationInfo . ElementName , value ) ;
306
- }
307
- else
308
- {
309
- return Query . Not ( serializationInfo . ElementName ) . Size ( value ) ;
310
- }
297
+ serializationInfo = GetSerializationInfo ( memberExpression ) ;
311
298
}
312
299
}
313
300
}
314
301
}
315
302
303
+ if ( serializationInfo != null )
304
+ {
305
+ if ( binaryExpression . NodeType == ExpressionType . Equal )
306
+ {
307
+ return Query . Size ( serializationInfo . ElementName , value ) ;
308
+ }
309
+ else
310
+ {
311
+ return Query . Not ( serializationInfo . ElementName ) . Size ( value ) ;
312
+ }
313
+ }
314
+
316
315
return null ;
317
316
}
318
317
@@ -331,7 +330,8 @@ private IMongoQuery BuildBooleanQuery(Expression expression)
331
330
332
331
private IMongoQuery BuildComparisonQuery ( BinaryExpression binaryExpression )
333
332
{
334
- if ( binaryExpression . NodeType == ExpressionType . Equal || binaryExpression . NodeType == ExpressionType . NotEqual )
333
+ var operatorNodeType = binaryExpression . NodeType ;
334
+ if ( operatorNodeType == ExpressionType . Equal || operatorNodeType == ExpressionType . NotEqual )
335
335
{
336
336
var query = BuildArrayLengthQuery ( binaryExpression ) ;
337
337
if ( query != null )
@@ -346,49 +346,57 @@ private IMongoQuery BuildComparisonQuery(BinaryExpression binaryExpression)
346
346
}
347
347
}
348
348
349
- var valueExpression = binaryExpression . Right as ConstantExpression ;
350
- if ( valueExpression != null )
349
+ // the constant could be on either side
350
+ var variableExpression = binaryExpression . Left ;
351
+ var constantExpression = binaryExpression . Right as ConstantExpression ;
352
+ if ( constantExpression == null )
351
353
{
352
- var unaryExpression = binaryExpression . Left as UnaryExpression ;
353
- if ( unaryExpression != null && unaryExpression . NodeType == ExpressionType . Convert && unaryExpression . Operand . Type . IsEnum )
354
+ constantExpression = binaryExpression . Left as ConstantExpression ;
355
+ variableExpression = binaryExpression . Right ;
356
+ // if the constant was on the left some operators need to be flipped
357
+ switch ( operatorNodeType )
354
358
{
355
- var enumType = unaryExpression . Operand . Type ;
356
- if ( unaryExpression . Type == Enum . GetUnderlyingType ( enumType ) )
357
- {
358
- var enumSerializationInfo = GetSerializationInfo ( unaryExpression . Operand ) ;
359
- if ( enumSerializationInfo != null )
360
- {
361
- var numericValue = valueExpression . Value ;
362
- var enumValue = Enum . ToObject ( enumType , numericValue ) ;
363
- var serializedValue = SerializeValue ( enumSerializationInfo , enumValue ) ;
364
- switch ( binaryExpression . NodeType )
365
- {
366
- case ExpressionType . Equal : return Query . EQ ( enumSerializationInfo . ElementName , serializedValue ) ;
367
- case ExpressionType . GreaterThan : return Query . GT ( enumSerializationInfo . ElementName , serializedValue ) ;
368
- case ExpressionType . GreaterThanOrEqual : return Query . GTE ( enumSerializationInfo . ElementName , serializedValue ) ;
369
- case ExpressionType . LessThan : return Query . LT ( enumSerializationInfo . ElementName , serializedValue ) ;
370
- case ExpressionType . LessThanOrEqual : return Query . LTE ( enumSerializationInfo . ElementName , serializedValue ) ;
371
- case ExpressionType . NotEqual : return Query . NE ( enumSerializationInfo . ElementName , serializedValue ) ;
372
- }
373
- }
374
- }
359
+ case ExpressionType . LessThan : operatorNodeType = ExpressionType . GreaterThan ; break ;
360
+ case ExpressionType . LessThanOrEqual : operatorNodeType = ExpressionType . GreaterThanOrEqual ; break ;
361
+ case ExpressionType . GreaterThan : operatorNodeType = ExpressionType . LessThan ; break ;
362
+ case ExpressionType . GreaterThanOrEqual : operatorNodeType = ExpressionType . LessThanOrEqual ; break ;
363
+ }
364
+ }
375
365
376
- return null ;
377
- }
378
-
379
- var serializationInfo = GetSerializationInfo ( binaryExpression . Left ) ;
380
- if ( serializationInfo != null )
366
+ if ( constantExpression == null )
367
+ {
368
+ return null ;
369
+ }
370
+
371
+ BsonSerializationInfo serializationInfo = null ;
372
+ var value = constantExpression . Value ;
373
+
374
+ var unaryExpression = variableExpression as UnaryExpression ;
375
+ if ( unaryExpression != null && unaryExpression . NodeType == ExpressionType . Convert && unaryExpression . Operand . Type . IsEnum )
376
+ {
377
+ var enumType = unaryExpression . Operand . Type ;
378
+ if ( unaryExpression . Type == Enum . GetUnderlyingType ( enumType ) )
381
379
{
382
- var serializedValue = SerializeValue ( serializationInfo , valueExpression . Value ) ;
383
- switch ( binaryExpression . NodeType )
384
- {
385
- case ExpressionType . Equal : return Query . EQ ( serializationInfo . ElementName , serializedValue ) ;
386
- case ExpressionType . GreaterThan : return Query . GT ( serializationInfo . ElementName , serializedValue ) ;
387
- case ExpressionType . GreaterThanOrEqual : return Query . GTE ( serializationInfo . ElementName , serializedValue ) ;
388
- case ExpressionType . LessThan : return Query . LT ( serializationInfo . ElementName , serializedValue ) ;
389
- case ExpressionType . LessThanOrEqual : return Query . LTE ( serializationInfo . ElementName , serializedValue ) ;
390
- case ExpressionType . NotEqual : return Query . NE ( serializationInfo . ElementName , serializedValue ) ;
391
- }
380
+ serializationInfo = GetSerializationInfo ( unaryExpression . Operand ) ;
381
+ value = Enum . ToObject ( enumType , value ) ; // serialize enum instead of underlying integer
382
+ }
383
+ }
384
+ else
385
+ {
386
+ serializationInfo = GetSerializationInfo ( variableExpression ) ;
387
+ }
388
+
389
+ if ( serializationInfo != null )
390
+ {
391
+ var serializedValue = SerializeValue ( serializationInfo , value ) ;
392
+ switch ( operatorNodeType )
393
+ {
394
+ case ExpressionType . Equal : return Query . EQ ( serializationInfo . ElementName , serializedValue ) ;
395
+ case ExpressionType . GreaterThan : return Query . GT ( serializationInfo . ElementName , serializedValue ) ;
396
+ case ExpressionType . GreaterThanOrEqual : return Query . GTE ( serializationInfo . ElementName , serializedValue ) ;
397
+ case ExpressionType . LessThan : return Query . LT ( serializationInfo . ElementName , serializedValue ) ;
398
+ case ExpressionType . LessThanOrEqual : return Query . LTE ( serializationInfo . ElementName , serializedValue ) ;
399
+ case ExpressionType . NotEqual : return Query . NE ( serializationInfo . ElementName , serializedValue ) ;
392
400
}
393
401
}
394
402
0 commit comments