|
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.
|