@@ -215,30 +215,30 @@ public static Expression GetMemberSource(Expression expression)
215
215
return currentExpression ;
216
216
}
217
217
218
- public static BsonDocument TranslateConditional ( Expression expression )
218
+ public static BsonDocument TranslateConditional ( Expression expression , bool negated = false )
219
219
{
220
220
var localExpression = UnwrapLambda ( expression ) ;
221
221
222
- static void UnwrapBinaryQuery ( BsonArray target , ExpressionType expressionType , BinaryExpression expression )
222
+ static void UnwrapBinaryQuery ( BsonArray target , ExpressionType expressionType , BinaryExpression expression , bool negated )
223
223
{
224
224
if ( expression . Left . NodeType == expressionType )
225
225
{
226
- UnwrapBinaryQuery ( target , expressionType , expression . Left as BinaryExpression ) ;
226
+ UnwrapBinaryQuery ( target , expressionType , expression . Left as BinaryExpression , negated ) ;
227
227
}
228
228
else
229
229
{
230
- target . Add ( TranslateSubExpression ( expression . Left ) ) ;
230
+ target . Add ( TranslateConditional ( expression . Left , negated ) ) ;
231
231
}
232
232
233
- target . Add ( TranslateSubExpression ( expression . Right ) ) ;
233
+ target . Add ( TranslateConditional ( expression . Right , negated ) ) ;
234
234
}
235
235
236
236
if ( localExpression is BinaryExpression binaryExpression )
237
237
{
238
238
if ( localExpression . NodeType == ExpressionType . AndAlso )
239
239
{
240
240
var unwrappedQuery = new BsonArray ( ) ;
241
- UnwrapBinaryQuery ( unwrappedQuery , ExpressionType . AndAlso , binaryExpression ) ;
241
+ UnwrapBinaryQuery ( unwrappedQuery , ExpressionType . AndAlso , binaryExpression , negated ) ;
242
242
243
243
var elements = new BsonElement [ unwrappedQuery . Count ] ;
244
244
@@ -252,7 +252,7 @@ static void UnwrapBinaryQuery(BsonArray target, ExpressionType expressionType, B
252
252
else if ( localExpression . NodeType == ExpressionType . OrElse )
253
253
{
254
254
var unwrappedQuery = new BsonArray ( ) ;
255
- UnwrapBinaryQuery ( unwrappedQuery , ExpressionType . OrElse , binaryExpression ) ;
255
+ UnwrapBinaryQuery ( unwrappedQuery , ExpressionType . OrElse , binaryExpression , negated ) ;
256
256
return new BsonDocument
257
257
{
258
258
{ "$or" , unwrappedQuery }
@@ -289,25 +289,34 @@ static void UnwrapBinaryQuery(BsonArray target, ExpressionType expressionType, B
289
289
290
290
var expressionOperator = ComparatorToStringMap [ expressionType ] ;
291
291
var valueComparison = new BsonDocument { { expressionOperator , value } } ;
292
+
293
+ if ( negated )
294
+ {
295
+ valueComparison = new BsonDocument
296
+ {
297
+ { "$not" , valueComparison }
298
+ } ;
299
+ }
300
+
292
301
return new BsonDocument { { fieldName , valueComparison } } ;
293
302
}
294
303
}
295
304
else if ( localExpression is UnaryExpression unaryExpression && unaryExpression . NodeType == ExpressionType . Not )
296
305
{
297
- string operatorName ;
298
306
if ( unaryExpression . Operand . NodeType == ExpressionType . OrElse )
299
307
{
300
- operatorName = "$nor" ;
308
+ var translatedInnerExpression = TranslateConditional ( unaryExpression . Operand , false ) ;
309
+ var valueItems = translatedInnerExpression . GetElement ( "$or" ) . Value ;
310
+
311
+ return new BsonDocument
312
+ {
313
+ { "$nor" , valueItems }
314
+ } ;
301
315
}
302
316
else
303
317
{
304
- operatorName = "$not" ;
318
+ return TranslateConditional ( unaryExpression . Operand , ! negated ) ;
305
319
}
306
-
307
- return new BsonDocument
308
- {
309
- { operatorName , TranslateConditional ( unaryExpression . Operand ) }
310
- } ;
311
320
}
312
321
313
322
throw new ArgumentException ( $ "Unexpected node type { expression . NodeType } for a conditional statement") ;
0 commit comments