Skip to content

Commit cb04999

Browse files
committed
Fixed #44 (Casting a int to a nullable int)
1 parent 8a012ef commit cb04999

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

src/System.Linq.Dynamic.Core/ExpressionParser.cs

+19-7
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ Expression ParseTypeAccess(Type type)
12671267
{
12681268
int errorPos = _textParser.CurrentToken.Pos;
12691269
_textParser.NextToken();
1270+
12701271
if (_textParser.CurrentToken.Id == TokenId.Question)
12711272
{
12721273
if (!type.GetTypeInfo().IsValueType || IsNullableType(type))
@@ -1280,23 +1281,36 @@ Expression ParseTypeAccess(Type type)
12801281
bool shorthand = _textParser.CurrentToken.Id == TokenId.StringLiteral;
12811282
if (_textParser.CurrentToken.Id == TokenId.OpenParen || shorthand)
12821283
{
1283-
Expression[] args = shorthand
1284-
? new[] { ParseStringLiteral() }
1285-
: ParseArgumentList();
1284+
Expression[] args = shorthand ? new[] { ParseStringLiteral() } : ParseArgumentList();
1285+
1286+
// If only 1 argument, and if the type is a Nullable, just make Nullable
1287+
if (args.Length == 1)
1288+
{
1289+
Type argType = args[0].Type;
1290+
1291+
if (type.GetTypeInfo().IsValueType && IsNullableType(type) && argType.GetTypeInfo().IsValueType)
1292+
{
1293+
return Expression.Convert(args[0], type);
1294+
}
1295+
}
12861296

12871297
MethodBase method;
12881298
switch (FindBestMethod(type.GetConstructors(), args, out method))
12891299
{
12901300
case 0:
12911301
if (args.Length == 1)
12921302
return GenerateConversion(args[0], type, errorPos);
1303+
12931304
throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type));
1305+
12941306
case 1:
12951307
return Expression.New((ConstructorInfo)method, args);
1308+
12961309
default:
12971310
throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type));
12981311
}
12991312
}
1313+
13001314
_textParser.ValidateToken(TokenId.Dot, Res.DotOrOpenParenOrStringLiteralExpected);
13011315
_textParser.NextToken();
13021316

@@ -1311,12 +1325,10 @@ static Expression GenerateConversion(Expression expr, Type type, int errorPos)
13111325

13121326
if (exprType.GetTypeInfo().IsValueType && type.GetTypeInfo().IsValueType)
13131327
{
1314-
if ((IsNullableType(exprType) || IsNullableType(type)) &&
1315-
GetNonNullableType(exprType) == GetNonNullableType(type))
1328+
if ((IsNullableType(exprType) || IsNullableType(type)) && GetNonNullableType(exprType) == GetNonNullableType(type))
13161329
return Expression.Convert(expr, type);
13171330

1318-
if ((IsNumericType(exprType) || IsEnumType(exprType)) &&
1319-
IsNumericType(type) || IsEnumType(type))
1331+
if ((IsNumericType(exprType) || IsEnumType(exprType)) && IsNumericType(type) || IsEnumType(type))
13201332
return Expression.ConvertChecked(expr, type);
13211333
}
13221334

test/System.Linq.Dynamic.Core.Tests/EntitiesTests.Cast.cs

+25-9
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,48 @@ namespace System.Linq.Dynamic.Core.Tests
44
{
55
public partial class EntitiesTests
66
{
7-
// [Fact] https://github.com/StefH/System.Linq.Dynamic.Core/issues/44
7+
// https://github.com/StefH/System.Linq.Dynamic.Core/issues/44
8+
[Fact]
89
public void Cast_To_nullableint()
910
{
1011
// Arrange
1112
PopulateTestData(1, 0);
1213

1314
// Act
14-
var expectedResult = _context.Blogs.Select(b => (int?)b.BlogId);
15-
var result = _context.Blogs.AsQueryable().Select("int?(BlogId)");
15+
var expectedResult = _context.Blogs.Select(b => (int?)b.BlogId).Count();
16+
var result = _context.Blogs.AsQueryable().Select("int?(BlogId)").Count();
1617

1718
// Assert
18-
Assert.Equal(expectedResult.ToArray(), result.ToDynamicArray<int?>());
19+
Assert.Equal(expectedResult, result);
1920
}
2021

21-
// [Fact] https://github.com/StefH/System.Linq.Dynamic.Core/issues/44
22+
[Fact]
23+
public void Cast_To_nullablelong()
24+
{
25+
// Arrange
26+
PopulateTestData(1, 0);
27+
28+
// Act
29+
var expectedResult = _context.Blogs.Select(b => (long?)b.BlogId).Count();
30+
var result = _context.Blogs.AsQueryable().Select("long?(BlogId)").Count();
31+
32+
// Assert
33+
Assert.Equal(expectedResult, result);
34+
}
35+
36+
// https://github.com/StefH/System.Linq.Dynamic.Core/issues/44
37+
[Fact]
2238
public void Cast_To_newnullableint()
2339
{
2440
// Arrange
2541
PopulateTestData(1, 0);
2642

2743
// Act
28-
var expectedResult = _context.Blogs.Select(x => new { i = (int?)x.BlogId });
29-
var result = _context.Blogs.AsQueryable().Select("new (int?(BlogId) as i)");
30-
44+
var expectedResult = _context.Blogs.Select(x => new { i = (int?)x.BlogId }).Count();
45+
var result = _context.Blogs.AsQueryable().Select("new (int?(BlogId) as i)").Count();
46+
3147
//Assert
32-
Assert.Equal(expectedResult.Count(), result.Count());
48+
Assert.Equal(expectedResult, result);
3349
}
3450
}
3551
}

test/System.Linq.Dynamic.Core.Tests/QueryableTests.Count.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void Count_Predicate()
3232

3333
//Act
3434
int expected = queryable.Count(u => u.Income > 50);
35-
int result = (queryable as IQueryable).Count("Income > 50");
35+
int result = queryable.Count("Income > 50");
3636

3737
//Assert
3838
Assert.Equal(expected, result);
@@ -48,7 +48,7 @@ public void Count_Predicate_WithArgs()
4848

4949
//Act
5050
int expected = queryable.Count(u => u.Income > value);
51-
int result = (queryable as IQueryable).Count("Income > @0", value);
51+
int result = queryable.Count("Income > @0", value);
5252

5353
//Assert
5454
Assert.Equal(expected, result);

0 commit comments

Comments
 (0)