|
From: <pa...@us...> - 2011-01-17 04:00:37
|
Revision: 5357
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5357&view=rev
Author: patearl
Date: 2011-01-17 04:00:30 +0000 (Mon, 17 Jan 2011)
Log Message:
-----------
Linq: Generate left joins for order by clauses. (NH-2412)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs
Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2011-01-16 22:48:45 UTC (rev 5356)
+++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2011-01-17 04:00:30 UTC (rev 5357)
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq.Expressions;
+using NHibernate.Linq.Visitors;
using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses;
-namespace NHibernate.Linq.Visitors
+namespace NHibernate.Linq.ReWriters
{
public class AddLeftJoinsReWriter : QueryModelVisitorBase
{
@@ -24,20 +24,37 @@
public override void VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
{
- var joins = LeftJoinDetector.Detect(selectClause.Selector, new NameGenerator(queryModel), _sessionFactory);
+ selectClause.Selector = JoinReplacer(queryModel, selectClause.Selector);
+ }
- if (joins.Joins.Count > 0)
- {
- selectClause.Selector = joins.Selector;
+ public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index)
+ {
+ foreach (Ordering ordering in orderByClause.Orderings)
+ {
+ ordering.Expression = JoinReplacer(queryModel, ordering.Expression);
+ }
+ }
- queryModel.TransformExpressions(e => ExpressionSwapper.Swap(e, joins.ExpressionMap));
+ private Expression JoinReplacer(QueryModel queryModel, Expression expression)
+ {
+ var joins = LeftJoinDetector.Detect(expression, new NameGenerator(queryModel), _sessionFactory);
- foreach (var join in joins.Joins)
- {
- queryModel.BodyClauses.Add(join);
- }
- }
- }
+ Expression result = expression;
+
+ if (joins.Joins.Count > 0)
+ {
+ result = joins.Selector;
+
+ queryModel.TransformExpressions(e => ExpressionSwapper.Swap(e, joins.ExpressionMap));
+
+ foreach (var join in joins.Joins)
+ {
+ queryModel.BodyClauses.Add(join);
+ }
+ }
+
+ return result;
+ }
}
public class ExpressionSwapper : NhExpressionTreeVisitor
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs 2011-01-17 04:00:30 UTC (rev 5357)
@@ -0,0 +1,11 @@
+using System;
+using System.Collections;
+
+namespace NHibernate.Test.NHSpecificTest.NH2412
+{
+ public class Customer
+ {
+ public int? Id { get; set; }
+ public string Name { get; set; }
+ }
+}
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs 2011-01-17 04:00:30 UTC (rev 5357)
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NHibernate.Criterion;
+using NHibernate.Linq;
+using NHibernate.Linq.Functions;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH2412
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnTearDown()
+ {
+ using (ISession s = sessions.OpenSession())
+ {
+ s.Delete("from Order");
+ s.Delete("from Customer");
+ s.Flush();
+ }
+ }
+
+ [Test]
+ public void OrderByUsesLeftJoin()
+ {
+ ISession s = OpenSession();
+ try
+ {
+ Customer c1 = new Customer {Name = "Allen"};
+ s.Save(c1);
+ Customer c2 = new Customer {Name = "Bob"};
+ s.Save(c2);
+ Customer c3 = new Customer {Name = "Charlie"};
+ s.Save(c3);
+
+ s.Save(new Order {Customer = c1});
+ s.Save(new Order {Customer = c3});
+ s.Save(new Order {Customer = c2});
+ s.Save(new Order());
+
+ s.Flush();
+ }
+ finally
+ {
+ s.Close();
+ }
+
+ s = OpenSession();
+ try
+ {
+ var orders = s.Query<Order>().OrderBy(o => o.Customer.Name).ToList();
+ Assert.AreEqual(4, orders.Count);
+ if (orders[0].Customer == null)
+ {
+ CollectionAssert.AreEqual(new[] {"Allen", "Bob", "Charlie"}, orders.Skip(1).Select(o => o.Customer.Name).ToArray());
+ }
+ else
+ {
+ CollectionAssert.AreEqual(new[] { "Allen", "Bob", "Charlie" }, orders.Take(3).Select(o => o.Customer.Name).ToArray());
+ }
+ }
+ finally
+ {
+ s.Close();
+ }
+ }
+ }
+}
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml 2011-01-17 04:00:30 UTC (rev 5357)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2412" default-lazy="false">
+ <class name="Customer" table="customers">
+ <id name="Id" column="id" unsaved-value="null">
+ <generator class="native" />
+ </id>
+ <property name="Name"/>
+ </class>
+ <class name="Order" table="orders">
+ <id name="Id" column="id" unsaved-value="null">
+ <generator class="native" />
+ </id>
+ <many-to-one name="Customer" class="Customer" column="customerid"/>
+ </class>
+</hibernate-mapping>
Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs 2011-01-17 04:00:30 UTC (rev 5357)
@@ -0,0 +1,11 @@
+using System;
+using System.Collections;
+
+namespace NHibernate.Test.NHSpecificTest.NH2412
+{
+ public class Order
+ {
+ public int? Id { get; set; }
+ public Customer Customer { get; set; }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 22:48:45 UTC (rev 5356)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-17 04:00:30 UTC (rev 5357)
@@ -579,6 +579,9 @@
<Compile Include="NHSpecificTest\NH2409\Message.cs" />
<Compile Include="NHSpecificTest\NH2409\MessageReading.cs" />
<Compile Include="NHSpecificTest\NH2409\User.cs" />
+ <Compile Include="NHSpecificTest\NH2412\Order.cs" />
+ <Compile Include="NHSpecificTest\NH2412\Customer.cs" />
+ <Compile Include="NHSpecificTest\NH2412\Fixture.cs" />
<Compile Include="NHSpecificTest\NH2420\DummyEnlistment.cs" />
<Compile Include="NHSpecificTest\NH2420\Fixture.cs" />
<Compile Include="NHSpecificTest\NH2420\MyTable.cs" />
@@ -2378,6 +2381,7 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="NHSpecificTest\NH2412\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2280\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2203\Mappings.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\BagWithLazyExtraAndFilter\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|