|
From: <pa...@us...> - 2011-01-16 20:55:20
|
Revision: 5354
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5354&view=rev
Author: patearl
Date: 2011-01-16 20:55:13 +0000 (Sun, 16 Jan 2011)
Log Message:
-----------
Linq: Fixed group by on multiple keys. Added more group by tests.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-01-16 20:48:51 UTC (rev 5353)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-01-16 20:55:13 UTC (rev 5354)
@@ -321,9 +321,9 @@
return new HqlDirectionDescending(_factory);
}
- public HqlGroupBy GroupBy(HqlExpression expression)
+ public HqlGroupBy GroupBy(params HqlExpression[] expressions)
{
- return new HqlGroupBy(_factory, expression);
+ return new HqlGroupBy(_factory, expressions);
}
public HqlAll All()
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-01-16 20:48:51 UTC (rev 5353)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-01-16 20:55:13 UTC (rev 5354)
@@ -786,7 +786,7 @@
public class HqlGroupBy : HqlStatement
{
- public HqlGroupBy(IASTFactory factory, HqlExpression expression) : base(HqlSqlWalker.GROUP, "group by", factory, expression)
+ public HqlGroupBy(IASTFactory factory, params HqlExpression[] expressions) : base(HqlSqlWalker.GROUP, "group by", factory, expressions)
{
}
}
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs 2011-01-16 20:48:51 UTC (rev 5353)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs 2011-01-16 20:55:13 UTC (rev 5354)
@@ -1,5 +1,8 @@
-using NHibernate.Hql.Ast;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using NHibernate.Hql.Ast;
using Remotion.Data.Linq.Clauses.ResultOperators;
+using System.Linq;
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
{
@@ -7,9 +10,15 @@
{
public void Process(GroupResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
{
- tree.AddGroupByClause(tree.TreeBuilder.GroupBy(
- HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.KeySelector, queryModelVisitor.VisitorParameters)
- .AsExpression()));
+ IEnumerable<Expression> groupByKeys;
+ if (resultOperator.KeySelector is NewExpression)
+ groupByKeys = (resultOperator.KeySelector as NewExpression).Arguments;
+ else
+ groupByKeys = new[] {resultOperator.KeySelector};
+
+ IEnumerable<HqlExpression> hqlGroupByKeys = groupByKeys.Select(k => HqlGeneratorExpressionTreeVisitor.Visit(k, queryModelVisitor.VisitorParameters).AsExpression());
+
+ tree.AddGroupByClause(tree.TreeBuilder.GroupBy(hqlGroupByKeys.ToArray()));
}
}
}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs 2011-01-16 20:55:13 UTC (rev 5354)
@@ -0,0 +1,120 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NHibernate.DomainModel.Northwind.Entities;
+using NUnit.Framework;
+
+namespace NHibernate.Test.Linq.ByMethod
+{
+ [TestFixture]
+ public class GroupByTests : LinqTestCase
+ {
+ [Test]
+ public void SingleKeyGroupAndCount()
+ {
+ var orderCounts = db.Orders.GroupBy(o => o.Customer).Select(g => g.Count()).ToList();
+ Assert.AreEqual(89, orderCounts.Count);
+ Assert.AreEqual(830, orderCounts.Sum());
+ }
+
+ [Test]
+ public void MultipleKeyGroupAndCount()
+ {
+ var orderCounts = db.Orders.GroupBy(o => new {o.Customer, o.Employee}).Select(g => g.Count()).ToList();
+ Assert.AreEqual(464, orderCounts.Count);
+ Assert.AreEqual(830, orderCounts.Sum());
+ }
+
+ [Test]
+ [Ignore("Not working yet.")]
+ public void SingleKeyGrouping()
+ {
+ var orders = db.Orders.GroupBy(o => o.Customer).ToList();
+ Assert.That(orders.Count, Is.EqualTo(830));
+ CheckGrouping(orders, o => o.Customer);
+ }
+
+ [Test]
+ [Ignore("Not working yet.")]
+ public void MultipleKeyGrouping()
+ {
+ var orders = db.Orders.GroupBy(o => new { o.Customer, o.Employee }).ToList();
+ Assert.That(orders.Count, Is.EqualTo(830));
+
+ CheckGrouping(
+ orders.Select(g => new TupGrouping<Customer, Employee, Order>(g.Key.Customer, g.Key.Employee, g)),
+ o => o.Customer,
+ o => o.Employee);
+ }
+
+ private void CheckGrouping<TKey, TElement>(IEnumerable<IGrouping<TKey, TElement>> groupedItems, Func<TElement, TKey> groupBy)
+ {
+ HashSet<object> used = new HashSet<object>();
+ foreach (IGrouping<TKey, TElement> group in groupedItems)
+ {
+ Assert.IsFalse(used.Contains(group.Key));
+ used.Add(group.Key);
+
+ foreach (var item in group)
+ {
+ Assert.AreEqual(group.Key, groupBy(item));
+ }
+ }
+ }
+
+ private void CheckGrouping<TKey1, TKey2, TElement>(IEnumerable<TupGrouping<TKey1, TKey2, TElement>> groupedItems, Func<TElement, TKey1> groupBy1, Func<TElement, TKey2> groupBy2)
+ {
+ HashSet<object> used = new HashSet<object>();
+ foreach (IGrouping<Tup<TKey1, TKey2>, TElement> group in groupedItems)
+ {
+ Assert.IsFalse(used.Contains(group.Key.Item1));
+ used.Add(group.Key.Item1);
+ Assert.IsFalse(used.Contains(group.Key.Item2));
+ used.Add(group.Key.Item2);
+
+ foreach (var item in group)
+ {
+ Assert.AreEqual(group.Key.Item1, groupBy1(item));
+ Assert.AreEqual(group.Key.Item2, groupBy2(item));
+ }
+ }
+ }
+
+ private class TupGrouping<TKey1, TKey2, TElement> : IGrouping<Tup<TKey1, TKey2>, TElement>
+ {
+ private IEnumerable<TElement> Elements { get; set; }
+
+ public TupGrouping(TKey1 key1, TKey2 key2, IEnumerable<TElement> elements)
+ {
+ Key = new Tup<TKey1, TKey2>(key1, key2);
+ Elements = elements;
+ }
+
+ public IEnumerator<TElement> GetEnumerator()
+ {
+ return Elements.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public Tup<TKey1, TKey2> Key { get; private set; }
+ }
+
+ private class Tup<T1, T2>
+ {
+ public T1 Item1 { get; private set; }
+ public T2 Item2 { get; private set; }
+
+ public Tup(T1 item1, T2 item2)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ }
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 20:48:51 UTC (rev 5353)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 20:55:13 UTC (rev 5354)
@@ -4,10 +4,10 @@
namespace NHibernate.Test.NHSpecificTest.NH2362
{
- [Ignore("Not fixed yet.")]
public class Fixture : BugTestCase
{
[Test]
+ [Ignore("Not working yet.")]
public void CanParseMultipleGroupByAndSelect()
{
using (var session = OpenSession())
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 20:48:51 UTC (rev 5353)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 20:55:13 UTC (rev 5354)
@@ -427,6 +427,7 @@
<Compile Include="Linq\BinaryBooleanExpressionTests.cs" />
<Compile Include="Linq\BinaryExpressionOrdererTests.cs" />
<Compile Include="Linq\BooleanMethodExtensionExample.cs" />
+ <Compile Include="Linq\ByMethod\GroupByTests.cs" />
<Compile Include="Linq\CasingTest.cs" />
<Compile Include="Linq\CollectionAssert.cs" />
<Compile Include="Linq\CustomExtensionsExample.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|