Skip to content

Commit 0d6d5ec

Browse files
committed
Fix two failures in Not processing in expressions
Fix edge case in 'Not' processing, introduced with the other 'not' fix
1 parent ed2465b commit 0d6d5ec

File tree

4 files changed

+88
-11
lines changed

4 files changed

+88
-11
lines changed

RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Equalities/QueryGroupEqualityTest.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using Microsoft.VisualStudio.TestTools.UnitTesting;
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
24
using RepoDb.Enumerations;
35
using RepoDb.Extensions;
4-
using System.Collections;
5-
using System.Collections.Generic;
66

77
namespace RepoDb.UnitTests.Equalities
88
{
@@ -128,6 +128,22 @@ public void TestQueryGroupHashCodeEqualityForCollidedExpressions()
128128

129129
// Assert
130130
Assert.IsFalse(equal);
131+
Assert.AreEqual(objA.QueryGroups.Count, objB.QueryGroups.Count);
132+
}
133+
134+
[TestMethod]
135+
public void TestQueryGroupHashCodeEqualityForCollidedExpressions2()
136+
{
137+
// Prepare
138+
var objA = QueryGroup.Parse<EntityClass>(c => c.Id == 1 && !(c.Value != 1));
139+
var objB = QueryGroup.Parse<EntityClass>(c => c.Id != 1 && c.Value == 1);
140+
141+
// Act
142+
var equal = (objA.GetHashCode() == objB.GetHashCode());
143+
144+
// Assert
145+
Assert.IsFalse(equal);
146+
Assert.AreEqual(objA.QueryGroups?.Count, objB.QueryGroups?.Count);
131147
}
132148

133149
[TestMethod]

RepoDb.Core/RepoDb/QueryGroup/ParseExpression.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using RepoDb.Enumerations;
2-
using RepoDb.Extensions;
3-
using System;
1+
using System;
42
using System.Linq;
53
using System.Linq.Expressions;
4+
using RepoDb.Enumerations;
5+
using RepoDb.Extensions;
66

77
namespace RepoDb
88
{
@@ -145,12 +145,24 @@ private static QueryGroup Parse<TEntity>(BinaryExpression expression)
145145
private static QueryGroup Parse<TEntity>(UnaryExpression expression)
146146
where TEntity : class
147147
{
148-
return expression.Operand switch
148+
if (expression.NodeType == ExpressionType.Not || expression.NodeType == ExpressionType.Convert)
149149
{
150-
MemberExpression memberExpression => Parse<TEntity>(memberExpression, expression.NodeType),
151-
MethodCallExpression methodCallExpression => Parse<TEntity>(methodCallExpression, expression.NodeType),
152-
_ => null
153-
};
150+
// These two handle
151+
if (expression.Operand is MemberExpression memberExpression && Parse<TEntity>(memberExpression, expression.NodeType) is { } r1)
152+
return r1;
153+
else if (expression.Operand is MethodCallExpression methodCallExpression && Parse<TEntity>(methodCallExpression, expression.NodeType) is { } r2)
154+
return r2;
155+
}
156+
157+
if (Parse<TEntity>(expression.Operand) is { } r)
158+
{
159+
// Wrap result in A NOT expression
160+
return new QueryGroup(r, true);
161+
}
162+
else
163+
{
164+
throw new NotSupportedException($"Unary operation '{expression.NodeType}' is currently not supported.");
165+
}
154166
}
155167

156168
/*

RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/AdditionalDbTypesTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,55 @@ await connection.InsertAllAsync(
8888
Assert.IsTrue((await connection.QueryAsync<DateOnlyTestData>(where: x => x.DateOnlyNullable == new DateOnly(2026, 1, 1), transaction: t)).Count() == 1);
8989
}
9090

91+
[TestMethod]
92+
public async Task CompareValuesTests()
93+
{
94+
await using var connection = new SqlConnection(Database.ConnectionString);
95+
await connection.OpenAsync();
96+
await using var t = await connection.BeginTransactionAsync();
97+
98+
await connection.InsertAllAsync(
99+
new DateOnlyTestData[] {
100+
new()
101+
{
102+
DateOnly = new DateOnly(2024,1,1),
103+
DateOnlyNullable = null,
104+
},
105+
new ()
106+
{
107+
DateOnly = new DateOnly(2025,1,1),
108+
DateOnlyNullable = new DateOnly(2026,1,1),
109+
}
110+
},
111+
transaction: t);
112+
113+
114+
// This one used to fail with NotSupportedException as '!' was not interpreted correctly
115+
var notEqualValue = new DateOnly(2024, 1, 1);
116+
var n = await connection.UpdateAsync<DateOnlyTestData>(
117+
new()
118+
{
119+
DateOnly = new DateOnly(2027, 1, 1)
120+
},
121+
where: QueryGroup.Parse<DateOnlyTestData>(x => !(x.DateOnly == notEqualValue)),
122+
fields: Field.Parse<DateOnlyTestData>(x => x.DateOnly),
123+
transaction: t);
124+
125+
Assert.AreEqual(1, n);
126+
127+
// This one used to fail by silently ignoring the '!(x.DateOnlyNullable == notEqualValue2)' part
128+
var notEqualValue2 = new DateOnly(2029, 1, 1);
129+
var n2 = await connection.UpdateAsync<DateOnlyTestData>(
130+
new()
131+
{
132+
DateOnly = new DateOnly(2030, 1, 1)
133+
},
134+
where: QueryGroup.Parse<DateOnlyTestData>(x => x.DateOnlyNullable == null || !(x.DateOnlyNullable == notEqualValue2)),
135+
fields: Field.Parse<DateOnlyTestData>(x => x.DateOnly),
136+
transaction: t);
137+
Assert.AreEqual(2, n2);
138+
}
139+
91140

92141

93142
public class DateOnlyTestData

0 commit comments

Comments
 (0)