Skip to content

Commit e199b37

Browse files
mfaulconmfaulcon-mynexusslorello89
authored
Resolve LINQ expression translation for ==/!= null (#538)
* Fixes an issue with Linq expression translation where negation of the search term was not being correctly applied when the right term resolves to null (#536, #514) Addresses a NullReferenceException when translating an expression involving a literal null value (#536, #514) --------- Co-authored-by: Mark Faulcon <[email protected]> Co-authored-by: slorello89 <[email protected]>
1 parent 00d6c07 commit e199b37

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

src/Redis.OM/Common/ExpressionParserUtilities.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,11 @@ private static string TranslateAnyForEmbeddedObjects(MethodCallExpression exp, L
10381038

10391039
private static string ValueToString(object value)
10401040
{
1041+
if (value is null)
1042+
{
1043+
return "null";
1044+
}
1045+
10411046
Type valueType = value.GetType();
10421047

10431048
if (valueType == typeof(double) || Nullable.GetUnderlyingType(valueType) == typeof(double))

src/Redis.OM/Common/ExpressionTranslator.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,12 @@ internal static string TranslateBinaryExpression(BinaryExpression binExpression,
415415
if (rightResolvesToNull)
416416
{
417417
dialectNeeded |= 1 << 1;
418-
return $"(ismissing({leftContent}))";
418+
return binExpression.NodeType switch
419+
{
420+
ExpressionType.Equal => $"(ismissing({leftContent}))",
421+
ExpressionType.NotEqual => $"-(ismissing({leftContent}))",
422+
_ => throw new ArgumentException($"The expression node type {binExpression.NodeType} is not supported"),
423+
};
419424
}
420425

421426
var rightContent = ExpressionParserUtilities.GetOperandStringForQueryArgs(binExpression.Right, parameters, ref dialectNeeded, treatBooleanMemberAsUnary: true);

test/Redis.OM.Unit.Tests/RediSearchTests/SearchTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4156,5 +4156,22 @@ await _substitute.Received().ExecuteAsync("FT.SEARCH",
41564156
"0",
41574157
"100");
41584158
}
4159+
4160+
[Fact]
4161+
public async Task TestIsNotNull()
4162+
{
4163+
_substitute.ClearSubstitute();
4164+
_substitute.ExecuteAsync(Arg.Any<string>(), Arg.Any<object[]>()).Returns(_mockReply);
4165+
var collection = new RedisCollection<ObjectWithNullableStrings>(_substitute);
4166+
await collection.Where(x => x.String1 != null).ToListAsync();
4167+
await _substitute.Received().ExecuteAsync("FT.SEARCH",
4168+
$"{nameof(ObjectWithNullableStrings).ToLower()}-idx",
4169+
"-(ismissing(@String1))",
4170+
"DIALECT",
4171+
2,
4172+
"LIMIT",
4173+
"0",
4174+
"100");
4175+
}
41594176
}
41604177
}

0 commit comments

Comments
 (0)