Skip to content

Commit f55eecc

Browse files
committed
CSHARP-1431: fixed issue with a local Contains operation inside an Any predicate.
1 parent e5d8f60 commit f55eecc

File tree

6 files changed

+49
-7
lines changed

6 files changed

+49
-7
lines changed

src/MongoDB.Driver.Tests/Linq/Translators/PredicateTranslatorTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ public void Any_with_a_predicate_on_scalars()
121121
// })));
122122
}
123123

124+
[Test]
125+
public void Any_with_local_contains()
126+
{
127+
var local = new List<string> { "Delilah", "Dolphin" };
128+
129+
Assert(
130+
x => x.G.Any(g => local.Contains(g.D)),
131+
1,
132+
"{\"G.D\": { $in: [\"Delilah\", \"Dolphin\" ] } }");
133+
}
134+
124135
[Test]
125136
public void LocalIListContains()
126137
{

src/MongoDB.Driver/Linq/Expressions/ExtensionExpressionVisitor.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,18 @@ protected internal virtual Expression VisitPipeline(PipelineExpression node)
111111
{
112112
return node.Update(
113113
Visit(node.Source),
114-
Visit(node.Projector));
114+
Visit(node.Projector),
115+
VisitResultOperator(node.ResultOperator));
116+
}
117+
118+
protected internal virtual ResultOperator VisitResultOperator(ResultOperator resultOperator)
119+
{
120+
if (resultOperator == null)
121+
{
122+
return resultOperator;
123+
}
124+
125+
return resultOperator.Update(this);
115126
}
116127

117128
protected internal virtual Expression VisitSelect(SelectExpression node)

src/MongoDB.Driver/Linq/Expressions/PipelineExpression.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,13 @@ public override string ToString()
7979
return result;
8080
}
8181

82-
public PipelineExpression Update(Expression source, Expression projector)
82+
public PipelineExpression Update(Expression source, Expression projector, ResultOperator resultOperator)
8383
{
8484
if (source != _source ||
85-
projector != _projector)
85+
projector != _projector ||
86+
resultOperator != _resultOperator)
8687
{
87-
return new PipelineExpression(source, projector, _resultOperator);
88+
return new PipelineExpression(source, projector, resultOperator);
8889
}
8990

9091
return this;

src/MongoDB.Driver/Linq/Expressions/ResultOperator.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,10 @@ internal abstract class ResultOperator
2222
public abstract string Name { get; }
2323

2424
public abstract Type Type { get; }
25+
26+
protected internal virtual ResultOperator Update(ExtensionExpressionVisitor visitor)
27+
{
28+
return this;
29+
}
2530
}
2631
}

src/MongoDB.Driver/Linq/Expressions/ResultOperators/ContainsResultOperator.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,16 @@ public Expression Value
4242
{
4343
get { return _value; }
4444
}
45+
46+
protected internal override ResultOperator Update(ExtensionExpressionVisitor visitor)
47+
{
48+
var value = visitor.Visit(_value);
49+
if (value != _value)
50+
{
51+
return new ContainsResultOperator(value);
52+
}
53+
54+
return this;
55+
}
4556
}
4657
}

src/MongoDB.Driver/Linq/Translators/FieldNamePrefixer.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ protected internal override Expression VisitField(FieldExpression node)
5050

5151
protected internal override Expression VisitPipeline(PipelineExpression node)
5252
{
53-
// only do the root source of this one...
5453
var source = node.Source;
5554
var sourcedSource = source as ISourcedExpression;
5655
while (sourcedSource != null)
@@ -60,12 +59,16 @@ protected internal override Expression VisitPipeline(PipelineExpression node)
6059
}
6160

6261
var newSource = Visit(source);
62+
PipelineExpression newNode = node;
6363
if (newSource != source)
6464
{
65-
return ExpressionReplacer.Replace(node, source, newSource);
65+
newNode = (PipelineExpression)ExpressionReplacer.Replace(node, source, newSource);
6666
}
6767

68-
return node;
68+
return newNode.Update(
69+
newNode.Source,
70+
newNode.Projector,
71+
VisitResultOperator(newNode.ResultOperator));
6972
}
7073
}
7174
}

0 commit comments

Comments
 (0)