Skip to content

Commit ffce56e

Browse files
committed
Code review changes
1 parent 9da30bf commit ffce56e

File tree

7 files changed

+427
-33
lines changed

7 files changed

+427
-33
lines changed

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

Lines changed: 165 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
using System.Linq.Expressions;
1515
using System.Text.RegularExpressions;
1616
using NHibernate.DomainModel.Northwind.Entities;
17-
using NUnit.Framework;
1817
using NHibernate.Linq;
18+
using NUnit.Framework;
1919

2020
namespace NHibernate.Test.Linq
2121
{
@@ -30,7 +30,8 @@ public async Task UsingArrayParameterTwiceAsync()
3030
var ids = new[] {11008, 11019, 11039};
3131
await (AssertTotalParametersAsync(
3232
db.Orders.Where(o => ids.Contains(o.OrderId) && ids.Contains(o.OrderId)),
33-
ids.Length));
33+
ids.Length,
34+
1));
3435
}
3536

3637
[Test]
@@ -40,7 +41,8 @@ public async Task UsingTwoArrayParametersAsync()
4041
var ids2 = new[] {11008, 11019, 11039};
4142
await (AssertTotalParametersAsync(
4243
db.Orders.Where(o => ids.Contains(o.OrderId) && ids2.Contains(o.OrderId)),
43-
ids.Length + ids2.Length));
44+
ids.Length + ids2.Length,
45+
2));
4446
}
4547

4648
[Test]
@@ -49,7 +51,8 @@ public async Task UsingListParameterTwiceAsync()
4951
var ids = new List<int> {11008, 11019, 11039};
5052
await (AssertTotalParametersAsync(
5153
db.Orders.Where(o => ids.Contains(o.OrderId) && ids.Contains(o.OrderId)),
52-
ids.Count));
54+
ids.Count,
55+
1));
5356
}
5457

5558
[Test]
@@ -59,7 +62,8 @@ public async Task UsingTwoListParametersAsync()
5962
var ids2 = new List<int> {11008, 11019, 11039};
6063
await (AssertTotalParametersAsync(
6164
db.Orders.Where(o => ids.Contains(o.OrderId) && ids2.Contains(o.OrderId)),
62-
ids.Count + ids2.Count));
65+
ids.Count + ids2.Count,
66+
2));
6367
}
6468

6569
[Test]
@@ -108,6 +112,16 @@ public async Task UsingNegateValueTypeParameterAsync()
108112
2));
109113
}
110114

115+
[Test]
116+
public async Task UsingValueTypeParameterInArrayAsync()
117+
{
118+
var id = 11008;
119+
await (AssertTotalParametersAsync(
120+
db.Orders.Where(o => new[] {id, 11019}.Contains(o.OrderId) && new[] {id, 11019}.Contains(o.OrderId)),
121+
4,
122+
2));
123+
}
124+
111125
[Test]
112126
public async Task UsingTwoValueTypeParametersAsync()
113127
{
@@ -156,6 +170,22 @@ public async Task UsingTwoObjectPropertyParametersAsync()
156170
2));
157171
}
158172

173+
[Test]
174+
public async Task UsingParameterInWhereSkipTakeAsync()
175+
{
176+
var value3 = 1;
177+
var q1 = db.Products.Where(o => o.ProductId < value3).Take(value3).Skip(value3);
178+
await (AssertTotalParametersAsync(q1, 3));
179+
}
180+
181+
[Test]
182+
public async Task UsingParameterInTwoWhereAsync()
183+
{
184+
var value3 = 1;
185+
var q1 = db.Products.Where(o => o.ProductId < value3).Where(o => o.ProductId < value3);
186+
await (AssertTotalParametersAsync(q1, 1));
187+
}
188+
159189
[Test]
160190
public async Task UsingObjectNestedPropertyParameterTwiceAsync()
161191
{
@@ -213,18 +243,142 @@ public async Task UsingObjectPropertyParameterWithThirdLevelClosureAsync()
213243
1));
214244
}
215245

216-
private static async Task AssertTotalParametersAsync<T>(IQueryable<T> query, int parameterNumber, CancellationToken cancellationToken = default(CancellationToken))
246+
[Test]
247+
public async Task UsingParameterInDMLInsertIntoFourTimesAsync()
248+
{
249+
var value = "test";
250+
await (AssertTotalParametersAsync(
251+
QueryMode.Insert,
252+
db.Customers.Where(c => c.CustomerId == value),
253+
x => new Customer {CustomerId = value, ContactName = value, CompanyName = value},
254+
4));
255+
}
256+
257+
[Test]
258+
public async Task UsingFourParametersInDMLInsertIntoAsync()
259+
{
260+
var value = "test";
261+
var value2 = "test";
262+
var value3 = "test";
263+
var value4 = "test";
264+
await (AssertTotalParametersAsync(
265+
QueryMode.Insert,
266+
db.Customers.Where(c => c.CustomerId == value3),
267+
x => new Customer {CustomerId = value4, ContactName = value2, CompanyName = value},
268+
4));
269+
}
270+
271+
[Test]
272+
public async Task UsingParameterInDMLUpdateThreeTimesAsync()
273+
{
274+
var value = "test";
275+
await (AssertTotalParametersAsync(
276+
QueryMode.Update,
277+
db.Customers.Where(c => c.CustomerId == value),
278+
x => new Customer {ContactName = value, CompanyName = value},
279+
3));
280+
}
281+
282+
[Test]
283+
public async Task UsingThreeParametersInDMLUpdateAsync()
284+
{
285+
var value = "test";
286+
var value2 = "test";
287+
var value3 = "test";
288+
await (AssertTotalParametersAsync(
289+
QueryMode.Update,
290+
db.Customers.Where(c => c.CustomerId == value3),
291+
x => new Customer { ContactName = value2, CompanyName = value },
292+
3));
293+
}
294+
295+
[Test]
296+
public async Task UsingParameterInDMLDeleteTwiceAsync()
297+
{
298+
var value = "test";
299+
await (AssertTotalParametersAsync(
300+
QueryMode.Delete,
301+
db.Customers.Where(c => c.CustomerId == value && c.CompanyName == value),
302+
2));
303+
}
304+
305+
[Test]
306+
public async Task UsingTwoParametersInDMLDeleteAsync()
307+
{
308+
var value = "test";
309+
var value2 = "test";
310+
await (AssertTotalParametersAsync(
311+
QueryMode.Delete,
312+
db.Customers.Where(c => c.CustomerId == value && c.CompanyName == value2),
313+
2));
314+
}
315+
316+
private async Task AssertTotalParametersAsync<T>(IQueryable<T> query, int parameterNumber, int? linqParameterNumber = null, CancellationToken cancellationToken = default(CancellationToken))
217317
{
218318
using (var sqlSpy = new SqlLogSpy())
219319
{
320+
// In case of arrays linqParameterNumber and parameterNumber will be different
321+
Assert.That(
322+
GetLinqExpression(query).ParameterValuesByName.Count,
323+
Is.EqualTo(linqParameterNumber ?? parameterNumber),
324+
"Linq expression has different number of parameters");
325+
220326
await (query.ToListAsync(cancellationToken));
221-
var sqlParameters = sqlSpy.GetWholeLog().Split(';')[1];
222-
var matches = Regex.Matches(sqlParameters, @"([\d\w]+)[\s]+\=", RegexOptions.IgnoreCase);
327+
AssertParameters(sqlSpy, parameterNumber);
328+
}
329+
}
330+
331+
private static Task AssertTotalParametersAsync<T>(QueryMode queryMode, IQueryable<T> query, int parameterNumber, CancellationToken cancellationToken = default(CancellationToken))
332+
{
333+
return AssertTotalParametersAsync(queryMode, query, null, parameterNumber, cancellationToken);
334+
}
335+
336+
private static async Task AssertTotalParametersAsync<T>(QueryMode queryMode, IQueryable<T> query, Expression<Func<T, T>> expression, int parameterNumber, CancellationToken cancellationToken = default(CancellationToken))
337+
{
338+
var provider = query.Provider as INhQueryProvider;
339+
Assert.That(provider, Is.Not.Null);
223340

224-
// Due to ODBC drivers not supporting parameter names, we have to do a distinct of parameter names.
225-
var distinctParameters = matches.OfType<Match>().Select(m => m.Groups[1].Value.Trim()).Distinct().ToList();
226-
Assert.That(distinctParameters, Has.Count.EqualTo(parameterNumber));
341+
var dmlExpression = expression != null
342+
? DmlExpressionRewriter.PrepareExpression(query.Expression, expression)
343+
: query.Expression;
344+
345+
using (var sqlSpy = new SqlLogSpy())
346+
{
347+
Assert.That(await (provider.ExecuteDmlAsync<T>(queryMode, dmlExpression, cancellationToken)), Is.EqualTo(0), "The DML query updated the data"); // Avoid updating the data
348+
AssertParameters(sqlSpy, parameterNumber);
227349
}
228350
}
351+
352+
private static void AssertParameters(SqlLogSpy sqlSpy, int parameterNumber)
353+
{
354+
var sqlParameters = sqlSpy.GetWholeLog().Split(';')[1];
355+
var matches = Regex.Matches(sqlParameters, @"([\d\w]+)[\s]+\=", RegexOptions.IgnoreCase);
356+
357+
// Due to ODBC drivers not supporting parameter names, we have to do a distinct of parameter names.
358+
var distinctParameters = matches.OfType<Match>().Select(m => m.Groups[1].Value.Trim()).Distinct().ToList();
359+
Assert.That(distinctParameters, Has.Count.EqualTo(parameterNumber));
360+
}
361+
362+
private NhLinqExpression GetLinqExpression<T>(QueryMode queryMode, IQueryable<T> query, Expression<Func<T, T>> expression)
363+
{
364+
return GetLinqExpression(queryMode, DmlExpressionRewriter.PrepareExpression(query.Expression, expression));
365+
}
366+
367+
private NhLinqExpression GetLinqExpression<T>(QueryMode queryMode, IQueryable<T> query)
368+
{
369+
return GetLinqExpression(queryMode, query.Expression);
370+
}
371+
372+
private NhLinqExpression GetLinqExpression<T>(IQueryable<T> query)
373+
{
374+
return GetLinqExpression(QueryMode.Select, query.Expression);
375+
}
376+
377+
private NhLinqExpression GetLinqExpression(QueryMode queryMode, Expression expression)
378+
{
379+
return queryMode == QueryMode.Select
380+
? new NhLinqExpression(expression, Sfi)
381+
: new NhLinqDmlExpression<Customer>(queryMode, expression, Sfi);
382+
}
229383
}
230384
}

src/NHibernate.Test/Linq/ConstantTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,11 @@ public void ConstantInWhereDoesNotCauseManyKeys()
216216
where c.CustomerId == "ANATR"
217217
select c);
218218
var evalResult = NhRelinqQueryParser.PartialEvaluate(q1.Expression);
219-
var expression = ExpressionParameterVisitor.Visit(evalResult, Sfi, out var parameters1);
219+
var expression = ExpressionParameterVisitor.Visit(QueryMode.Select, evalResult, Sfi, out var parameters1);
220220
var k1 = ExpressionKeyVisitor.Visit(expression, parameters1);
221221

222222
var evalResult2 = NhRelinqQueryParser.PartialEvaluate(q1.Expression);
223-
var expression2 = ExpressionParameterVisitor.Visit(evalResult2, Sfi, out var parameters2);
223+
var expression2 = ExpressionParameterVisitor.Visit(QueryMode.Select, evalResult2, Sfi, out var parameters2);
224224
var k2 = ExpressionKeyVisitor.Visit(expression2, parameters2);
225225

226226
Assert.That(parameters1, Has.Count.GreaterThan(0), "parameters1");

0 commit comments

Comments
 (0)