Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix "in" for nullable Enums
  • Loading branch information
StefH committed Jun 10, 2025
commit 52bc6f77802b02c9e9ca1a93ff40f45c2578a472
4 changes: 2 additions & 2 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@
// we need to parse unary expressions because otherwise 'in' clause will fail in use cases like 'in (-1, -1)' or 'in (!true)'
Expression right = ParseUnary();

// if the identifier is an Enum, try to convert the right-side also to an Enum.
if (left.Type.GetTypeInfo().IsEnum)
// if the identifier is an Enum (or nullable Enum), try to convert the right-side also to an Enum.
if (TypeHelper.GetNonNullableType(left.Type).GetTypeInfo().IsEnum)
{
if (right is ConstantExpression constantExprRight)
{
Expand Down Expand Up @@ -1472,7 +1472,7 @@
}
else
{
if (!TryGetMemberName(expr, out propName)) // TODO : investigate this

Check warning on line 1475 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Complete the task associated to this 'TODO' comment. (https://rules.sonarsource.com/csharp/RSPEC-1135)
{
if (expr is MethodCallExpression methodCallExpression
&& methodCallExpression.Arguments.Count == 1
Expand Down Expand Up @@ -1950,7 +1950,7 @@
switch (member)
{
case PropertyInfo property:
var propertyIsStatic = property?.GetGetMethod().IsStatic ?? property?.GetSetMethod().IsStatic ?? false;

Check warning on line 1953 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Dereference of a possibly null reference.

Check warning on line 1953 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Dereference of a possibly null reference.

Check warning on line 1953 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Dereference of a possibly null reference.

Check warning on line 1953 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Dereference of a possibly null reference.

Check warning on line 1953 in src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

View workflow job for this annotation

GitHub Actions / Linux: Build and Tests

Dereference of a possibly null reference.
propertyOrFieldExpression = propertyIsStatic ? Expression.Property(null, property) : Expression.Property(expression, property);
return true;

Expand Down
28 changes: 22 additions & 6 deletions test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,10 +1269,6 @@ public void ExpressionTests_HexadecimalInteger()
[Fact]
public void ExpressionTests_In_Enum()
{
var config = new ParsingConfig();
#if NETSTANDARD
// config.CustomTypeProvider = new NetStandardCustomTypeProvider();
#endif
// Arrange
var model1 = new ModelWithEnum { TestEnum = TestEnum.Var1 };
var model2 = new ModelWithEnum { TestEnum = TestEnum.Var2 };
Expand All @@ -1281,8 +1277,28 @@ public void ExpressionTests_In_Enum()

// Act
var expected = qry.Where(x => new[] { TestEnum.Var1, TestEnum.Var2 }.Contains(x.TestEnum)).ToArray();
var result1 = qry.Where(config, "it.TestEnum in (\"Var1\", \"Var2\")").ToArray();
var result2 = qry.Where(config, "it.TestEnum in (0, 1)").ToArray();
var result1 = qry.Where("it.TestEnum in (\"Var1\", \"Var2\")").ToArray();
var result2 = qry.Where("it.TestEnum in (0, 1)").ToArray();

// Assert
Check.That(result1).ContainsExactly(expected);
Check.That(result2).ContainsExactly(expected);
}

[Fact]
public void ExpressionTests_In_EnumIsNullable()
{
// Arrange
var model1 = new ModelWithEnum { TestEnumNullable = TestEnum.Var1 };
var model2 = new ModelWithEnum { TestEnumNullable = TestEnum.Var2 };
var model3 = new ModelWithEnum { TestEnumNullable = TestEnum.Var3 };
var model4 = new ModelWithEnum { TestEnumNullable = null };
var qry = new[] { model1, model2, model3, model4 }.AsQueryable();

// Act
var expected = new[] { model1, model2 };
var result1 = qry.Where("it.TestEnumNullable in (\"Var1\", \"Var2\")").ToArray();
var result2 = qry.Where("it.TestEnumNullable in (0, 1)").ToArray();

// Assert
Check.That(result1).ContainsExactly(expected);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

namespace System.Linq.Dynamic.Core.Tests.Helpers.Models
namespace System.Linq.Dynamic.Core.Tests.Helpers.Models;

public class ModelWithEnum
{
public class ModelWithEnum
{
public string Name { get; set; }
public string Name { get; set; } = null!;

public TestEnum TestEnum { get; set; }

public TestEnum TestEnum { get; set; }
}
public TestEnum? TestEnumNullable { get; set; }
}
Loading