diff --git a/ChangeLog.txt b/ChangeLog.txt index 4d14491d..d72a46f6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,5 @@ https://github.com/GitTools/GitReleaseNotes -GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.8.11 +GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.8.12 GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags diff --git a/src/EntityFramework.DynamicLinq/EntityFramework.DynamicLinq.csproj b/src/EntityFramework.DynamicLinq/EntityFramework.DynamicLinq.csproj index a5805e1b..9f3a3c72 100644 --- a/src/EntityFramework.DynamicLinq/EntityFramework.DynamicLinq.csproj +++ b/src/EntityFramework.DynamicLinq/EntityFramework.DynamicLinq.csproj @@ -2,7 +2,7 @@ Dynamic Linq extensions for EntityFramework which adds Async support EntityFramework.DynamicLinq - 1.0.8.11 + 1.0.8.12 Stef Heyenrath net45;net46 EF diff --git a/src/Microsoft.EntityFrameworkCore.DynamicLinq/Microsoft.EntityFrameworkCore.DynamicLinq.csproj b/src/Microsoft.EntityFrameworkCore.DynamicLinq/Microsoft.EntityFrameworkCore.DynamicLinq.csproj index e817cc9c..7ffb396c 100644 --- a/src/Microsoft.EntityFrameworkCore.DynamicLinq/Microsoft.EntityFrameworkCore.DynamicLinq.csproj +++ b/src/Microsoft.EntityFrameworkCore.DynamicLinq/Microsoft.EntityFrameworkCore.DynamicLinq.csproj @@ -2,9 +2,9 @@ Dynamic Linq extensions for Microsoft.EntityFrameworkCore which adds Async support Microsoft.EntityFrameworkCore.DynamicLinq - 1.0.8.11 + 1.0.8.12 Stef Heyenrath - net451;net46;netstandard1.3;netstandard2.0;uap10.0 + net451;net46;netstandard1.3;netstandard2.0 $(DefineConstants);EFCORE true Microsoft.EntityFrameworkCore.DynamicLinq diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs index f1dd3eb3..ab4bd3c4 100644 --- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs +++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs @@ -1246,13 +1246,30 @@ private Expression CreateNewExpression(List properties, List)propertyInfos); + var expressionsPromoted = new List(); + + // Loop all expressions and promote if needed + for (int i = 0; i < propertyTypes.Length; i++) + { + Type propertyType = propertyTypes[i]; + Type expressionType = expressions[i].Type; + + // Promote from Type to Nullable Type if needed + expressionsPromoted.Add(ExpressionPromoter.Promote(expressions[i], propertyType, true, true)); + } + + return Expression.New(ctor, expressionsPromoted, (IEnumerable)propertyInfos); } MemberBinding[] bindings = new MemberBinding[properties.Count]; for (int i = 0; i < bindings.Length; i++) { - bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]); + PropertyInfo property = type.GetProperty(properties[i].Name); + Type propertyType = property.PropertyType; + Type expressionType = expressions[i].Type; + + // Promote from Type to Nullable Type if needed + bindings[i] = Expression.Bind(property, ExpressionPromoter.Promote(expressions[i], propertyType, true, true)); } return Expression.MemberInit(Expression.New(type), bindings); diff --git a/src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.csproj b/src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.csproj index 09e86275..a1997865 100644 --- a/src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.csproj +++ b/src/System.Linq.Dynamic.Core/System.Linq.Dynamic.Core.csproj @@ -2,9 +2,9 @@ This is a .NETStandard/ .NET Core port of the the Microsoft assembly for the .Net 4.0 Dynamic language functionality. System.Linq.Dynamic.Core - 1.0.8.11 + 1.0.8.12 Microsoft;Scott Guthrie;King Wilder;Nathan Arnott;Stef Heyenrath - net35;net40;net45;net46;uap10.0;netstandard1.3;netstandard2.0 + net35;net40;net45;net46;netstandard1.3;netstandard2.0 true System.Linq.Dynamic.Core System.Linq.Dynamic.Core.snk diff --git a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs index aac46b7c..41210139 100644 --- a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs +++ b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs @@ -5,6 +5,7 @@ using Linq.PropertyTranslator.Core; using QueryInterceptor.Core; using Xunit; +using NFluent; #if EFCORE using Microsoft.AspNetCore.Identity.EntityFrameworkCore; #else @@ -161,6 +162,71 @@ public void Select_Dynamic_IntoType() Assert.Equal(testList.Select(x => x.Profile).Cast().ToList(), userProfiles.ToDynamicList()); } + public class Example + { + public DateTime Time { get; set; } + public DayOfWeek? DOWNull { get; set; } + public DayOfWeek DOW { get; set; } + public int Sec { get; set; } + public int? SecNull { get; set; } + } + + public class ExampleWithConstructor + { + public DateTime Time { get; set; } + public DayOfWeek? DOWNull { get; set; } + public DayOfWeek DOW { get; set; } + public int Sec { get; set; } + public int? SecNull { get; set; } + + public ExampleWithConstructor(DateTime t, DayOfWeek? dn, DayOfWeek d, int s, int? sn) + { + Time = t; + DOWNull = dn; + DOW = d; + Sec = s; + SecNull = sn; + } + } + + [Fact] + public void Select_Dynamic_IntoTypeWithNullableProperties1() + { + // Arrange + var dates = Enumerable.Repeat(0, 7) + .Select((d, i) => new DateTime(2000, 1, 1).AddDays(i).AddSeconds(i)) + .AsQueryable(); + + // Act + IQueryable result = dates + .Select(d => new Example { Time = d, DOWNull = d.DayOfWeek, DOW = d.DayOfWeek, Sec = d.Second, SecNull = d.Second }); + IQueryable resultDynamic = dates + .Select("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)"); + + // Assert + Check.That(resultDynamic.First()).Equals(result.First()); + Check.That(resultDynamic.Last()).Equals(result.Last()); + } + + [Fact] + public void Select_Dynamic_IntoTypeWithNullableProperties2() + { + // Arrange + var dates = Enumerable.Repeat(0, 7) + .Select((d, i) => new DateTime(2000, 1, 1).AddDays(i).AddSeconds(i)) + .AsQueryable(); + + // Act + IQueryable result = dates + .Select(d => new ExampleWithConstructor(d, d.DayOfWeek, d.DayOfWeek, d.Second, d.Second)); + IQueryable resultDynamic = dates + .Select("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)"); + + // Assert + Check.That(resultDynamic.First()).Equals(result.First()); + Check.That(resultDynamic.Last()).Equals(result.Last()); + } + [Fact] public void Select_Dynamic_Exceptions() {