From: <pa...@us...> - 2010-12-25 00:40:56
|
Revision: 5337 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5337&view=rev Author: patearl Date: 2010-12-25 00:40:50 +0000 (Sat, 25 Dec 2010) Log Message: ----------- Added a workaround for a .NET bug (pre 4.0) to support adding null to a List<Nullable<T>>. This was required to fix a bug in nullable linq sums. Added more tests for linq sums. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Util/ArrayHelper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/SumTests.cs Modified: trunk/nhibernate/src/NHibernate/Util/ArrayHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/ArrayHelper.cs 2010-12-25 00:35:58 UTC (rev 5336) +++ trunk/nhibernate/src/NHibernate/Util/ArrayHelper.cs 2010-12-25 00:40:50 UTC (rev 5337) @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Data; +using System.Reflection; using System.Text; using NHibernate.SqlTypes; using NHibernate.Type; @@ -196,9 +197,41 @@ // NH-specific public static void AddAll(IList to, IList from) { + System.Action addNull = null; foreach (object obj in from) { - to.Add(obj); + // There is bug in .NET, before version 4, where adding null to a List<Nullable<T>> through the non-generic IList interface throws an exception. + // TODO: Everything but the to.Add(obj) should should be conditionally compiled only for versions of .NET earlier than 4. + if (obj == null) + { + if (addNull == null) + { + if (to.GetType().IsGenericType && + to.GetType().GetGenericTypeDefinition() == typeof(List<>) && + to.GetType().GetGenericArguments()[0].IsGenericType && + to.GetType().GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(Nullable<>)) + { + MethodInfo addMethod = to.GetType().GetMethod("Add"); + System.Linq.Expressions.MethodCallExpression addMethodCall = + System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression.Constant(to), + addMethod, + System.Linq.Expressions.Expression.Constant(null, to.GetType().GetGenericArguments()[0])); + System.Linq.Expressions.LambdaExpression addLambda = + System.Linq.Expressions.Expression.Lambda(addMethodCall); + + addNull = (System.Action) addLambda.Compile(); + } + else + { + addNull = () => to.Add(null); + } + } + addNull(); + } + else + { + to.Add(obj); + } } } Added: trunk/nhibernate/src/NHibernate.Test/Linq/SumTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/SumTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/SumTests.cs 2010-12-25 00:40:50 UTC (rev 5337) @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class SumTests : LinqTestCase + { + [Test] + [ExpectedException] + public void EmptySumDecimal() + { + db.OrderLines.Where(ol => false).Sum(ol => ol.Discount); + } + + [Test] + public void EmptySumCastNullableDecimal() + { + decimal total = db.OrderLines.Where(ol => false).Sum(ol => (decimal?)ol.Discount) ?? 0; + Assert.AreEqual(0, total); + } + + [Test] + public void SumDecimal() + { + decimal total = db.OrderLines.Sum(ol => ol.Discount); + Assert.Greater(total, 0); + } + + [Test] + public void EmptySumNullableDecimal() + { + decimal total = db.Orders.Where(ol => false).Sum(ol => ol.Freight) ?? 0; + Assert.AreEqual(0, total); + } + + [Test] + public void SumNullableDecimal() + { + decimal? total = db.Orders.Sum(ol => ol.Freight); + Assert.Greater(total, 0); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-12-25 00:35:58 UTC (rev 5336) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-12-25 00:40:50 UTC (rev 5337) @@ -454,6 +454,7 @@ <Compile Include="Linq\QueryReuseTests.cs" /> <Compile Include="Linq\ReadonlyTestCase.cs" /> <Compile Include="Linq\StatelessSessionQueringTest.cs" /> + <Compile Include="Linq\SumTests.cs" /> <Compile Include="Logging\Log4NetLoggerTest.cs" /> <Compile Include="Logging\LoggerProviderTest.cs" /> <Compile Include="NHSpecificTest\EntityNameAndCompositeId\Fixture.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |