Skip to content

Commit d6509b7

Browse files
committed
Fix parameters inside evaluatable expressions for Linq provider
1 parent 2011a77 commit d6509b7

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/NHibernate.Test/Async/Linq/ParameterTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,23 @@ public async Task UsingValueTypeParameterTwiceAsync()
125125
1));
126126
}
127127

128+
[Test]
129+
public async Task UsingParameterInEvaluatableExpressionAsync()
130+
{
131+
var value = "test";
132+
await (db.Orders.Where(o => string.Format("{0}", value) != o.ShippedTo).ToListAsync());
133+
await (db.Orders.Where(o => $"{value}_" != o.ShippedTo).ToListAsync());
134+
await (db.Orders.Where(o => string.Copy(value) != o.ShippedTo).ToListAsync());
135+
136+
var guid = Guid.Parse("2D7E6EB3-BD08-4A40-A4E7-5150F7895821");
137+
await (db.Orders.Where(o => o.ShippedTo.Contains($"VALUE {guid}")).ToListAsync());
138+
139+
var names = new[] {"name"};
140+
await (db.Users.Where(x => names.Length == 0 || names.Contains(x.Name)).ToListAsync());
141+
names = new string[] { };
142+
await (db.Users.Where(x => names.Length == 0 || names.Contains(x.Name)).ToListAsync());
143+
}
144+
128145
[Test]
129146
public async Task UsingNegateValueTypeParameterTwiceAsync()
130147
{

src/NHibernate.Test/Linq/ParameterTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ public void UsingValueTypeParameterTwice()
113113
1);
114114
}
115115

116+
[Test]
117+
public void UsingParameterInEvaluatableExpression()
118+
{
119+
var value = "test";
120+
db.Orders.Where(o => string.Format("{0}", value) != o.ShippedTo).ToList();
121+
db.Orders.Where(o => $"{value}_" != o.ShippedTo).ToList();
122+
db.Orders.Where(o => string.Copy(value) != o.ShippedTo).ToList();
123+
124+
var guid = Guid.Parse("2D7E6EB3-BD08-4A40-A4E7-5150F7895821");
125+
db.Orders.Where(o => o.ShippedTo.Contains($"VALUE {guid}")).ToList();
126+
127+
var names = new[] {"name"};
128+
db.Users.Where(x => names.Length == 0 || names.Contains(x.Name)).ToList();
129+
names = new string[] { };
130+
db.Users.Where(x => names.Length == 0 || names.Contains(x.Name)).ToList();
131+
}
132+
116133
[Test]
117134
public void ValidateMixingTwoParametersCacheKeys()
118135
{

src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ public override Expression Visit(Expression expression)
7777
if (expression == null)
7878
return null;
7979

80-
if (expression.NodeType == ExpressionType.Lambda || !_partialEvaluationInfo.IsEvaluatableExpression(expression))
80+
if (expression.NodeType == ExpressionType.Lambda || !_partialEvaluationInfo.IsEvaluatableExpression(expression) ||
81+
#region NH additions
82+
// Variables should be evaluated only when they are part of an evaluatable expression (e.g. o => string.Format("...", variable))
83+
expression is UnaryExpression unaryExpression &&
84+
ExpressionsHelper.IsVariable(unaryExpression.Operand, out _, out _))
85+
#endregion
8186
return base.Visit(expression);
8287

8388
Expression evaluatedExpression;
@@ -211,11 +216,6 @@ public override bool IsEvaluatableConstant(ConstantExpression node)
211216
return base.IsEvaluatableConstant(node);
212217
}
213218

214-
public override bool IsEvaluatableUnary(UnaryExpression node)
215-
{
216-
return !ExpressionsHelper.IsVariable(node.Operand, out _, out _);
217-
}
218-
219219
public override bool IsEvaluatableMember(MemberExpression node)
220220
{
221221
if (node == null)

0 commit comments

Comments
 (0)