@@ -59,6 +59,75 @@ public void Should_not_throw_the_exception_when_a_child_expression_is_called_fro
5959 Execute ( CreateWhereQuery ( expr ) ) ;
6060 }
6161
62+ [ Fact ]
63+ public void Should_not_throw_the_exception_when_a_child_expression_is_called_from_nested_locals ( )
64+ {
65+ Setup ( ) ;
66+
67+ var local = new List < int > { 1 , 2 } ;
68+ var local2 = new List < bool > { true , false } ;
69+
70+ Expression < Func < TestObject , bool > > expr = ( a ) => a . Collection1 . Any ( b => local . Any ( c => b . Collection2 . Contains ( c ) ) ) ;
71+ AssertWhere ( expr , "{ $match : { 'Collection2' : { '$in' : [1, 2] } } }" ) ;
72+
73+ expr = ( a ) => a . Collection1 . Any ( b => b . Collection1 . Any ( c => local . Any ( d => c . Collection2 . Contains ( d ) ) ) ) ;
74+ AssertWhere ( expr , "{ $match : { 'Collection2' : { '$in' : [1, 2] } } }" ) ;
75+
76+ expr = ( a ) => a . Collection1 . Any ( b => b . Collection2 != null && b . Collection1 . Any ( c => local . Any ( d => c . Collection2 . Contains ( d ) ) ) ) ;
77+ AssertWhere ( expr , "{ $match : { 'Collection1' : { '$elemMatch' : { 'Collection2' : { '$ne' : null, '$in' : [1, 2] } } } } }" ) ;
78+
79+ expr = ( a ) => a . Collection1 . Any (
80+ b =>
81+ b . Collection1 != null && b . Collection1 . Any (
82+ c =>
83+ local . Any ( d => c . Collection2 . Contains ( d ) ) &&
84+ local2 . Any ( e => c . Collection3 . Contains ( e ) )
85+ ) ) ;
86+ AssertWhere (
87+ expr ,
88+ @"{
89+ $match : {
90+ 'Collection1' : {
91+ '$elemMatch' : {
92+ 'Collection1' : {
93+ '$ne' : null,
94+ '$elemMatch' : {
95+ 'Collection2' : { '$in' : [1, 2] },
96+ 'Collection3' : { '$in' : [true, false] }
97+ }
98+ }
99+ }
100+ }
101+ }
102+ }" ) ;
103+
104+ expr = ( a ) => a . Collection1 . Any (
105+ b =>
106+ b . Collection1 != null && b . Collection1 . Any (
107+ c =>
108+ c . Collection1 . Any ( d => d . Value1 == 2 ) &&
109+ local2 . Any ( e => c . Collection3 . Contains ( e ) )
110+ ) ) ;
111+ AssertWhere (
112+ expr ,
113+ @"
114+ {
115+ $match : {
116+ 'Collection1' : {
117+ '$elemMatch' : {
118+ 'Collection1' : {
119+ '$ne' : null,
120+ '$elemMatch' : {
121+ 'Collection1' : { '$elemMatch' : { 'Value1' : 2 } },
122+ 'Collection3' : { '$in' : [true, false] }
123+ }
124+ }
125+ }
126+ }
127+ }
128+ }" ) ;
129+ }
130+
62131 [ Fact ]
63132 public void Should_not_throw_the_exception_when_a_predicate_has_only_parameter_expressions ( )
64133 {
@@ -175,6 +244,21 @@ public void Should_throw_the_exception_when_there_is_the_parent_parameter_in_the
175244 exception . Message . Should ( ) . Be ( string . Format ( NotSupportErrorMessageTemplate , "{document}{Collection1}.Where((({document}{Value1} != 3) AndAlso Any({document}{Collection1}.Where(({document}{Value1} != 5)))))" , "a" ) ) ;
176245 }
177246
247+ // private methods
248+ private void AssertWhere ( Expression < Func < TestObject , bool > > expression , string expectedStages )
249+ {
250+ var actualStages = Execute ( CreateWhereQuery ( expression ) ) ;
251+ var actual = new BsonDocument ( ) ;
252+ foreach ( var actualStage in actualStages )
253+ {
254+ actual . AddRange ( actualStage ) ;
255+ }
256+
257+ var expected = BsonDocument . Parse ( expectedStages ) ;
258+
259+ actual . Should ( ) . Be ( expected ) ;
260+ }
261+
178262 private IEnumerable < BsonDocument > Execute < T > ( IMongoQueryable < T > queryable )
179263 {
180264 var result = ( AggregateQueryableExecutionModel < T > ) queryable . GetExecutionModel ( ) ;
0 commit comments