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