Skip to content

Commit aa05f72

Browse files
author
Daniel Laberge
committed
Backported Add support for left outer join via navigation property (NH-2379), Add support for additional restrictions in nested selects and left outer joins (NH-3175) and NH-3459 Added support of Left Outer Joins with DefaultIfEmpty() in conjunction with group by.
(cherry picked from commits 35f3f20, 85fbbb0, 7d8d59f and 8c6bc18)
1 parent a52c918 commit aa05f72

File tree

18 files changed

+753
-29
lines changed

18 files changed

+753
-29
lines changed

src/NHibernate.Test/Linq/JoinTests.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
using System;
22
using System.Linq;
3-
using System.Linq.Expressions;
4-
using NHibernate.DomainModel.Northwind.Entities;
53
using NUnit.Framework;
64

75
namespace NHibernate.Test.Linq
86
{
97
[TestFixture]
108
public class JoinTests : LinqTestCase
119
{
12-
protected override void Configure(Cfg.Configuration configuration)
13-
{
14-
configuration.SetProperty(Cfg.Environment.ShowSql, "true");
15-
base.Configure(configuration);
16-
}
17-
18-
1910
[Test]
2011
public void OrderLinesWith2ImpliedJoinShouldProduce2JoinsInSql()
2112
{

src/NHibernate.Test/Linq/NestedSelectsTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,5 +346,23 @@ public void EmployeesIdAndWithSubordinatesId()
346346

347347
Assert.That(emplyees.Count, Is.EqualTo(9));
348348
}
349+
350+
[Test]
351+
public void OrdersIdWithOrderLinesNestedWhereId()
352+
{
353+
var orders = db.Orders
354+
.Select(o => new
355+
{
356+
o.OrderId,
357+
OrderLinesIds = o.OrderLines
358+
.Where(ol => ol.Discount > 1)
359+
.Select(ol => ol.Id)
360+
.ToArray()
361+
})
362+
.ToList();
363+
364+
Assert.That(orders.Count, Is.EqualTo(830));
365+
Assert.That(orders[0].OrderLinesIds, Is.Empty);
366+
}
349367
}
350368
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Linq;
5+
using NHibernate.Mapping.ByCode;
6+
using NUnit.Framework;
7+
8+
namespace NHibernate.Test.NHSpecificTest.NH2379
9+
{
10+
[TestFixture]
11+
public class Fixture : TestCaseMappingByCode
12+
{
13+
protected override HbmMapping GetMappings()
14+
{
15+
var mapper = new ModelMapper();
16+
mapper.Class<Order>(rc =>
17+
{
18+
rc.Table("Orders");
19+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
20+
rc.Property(x => x.Name);
21+
rc.Set(x => x.OrderLines, m =>
22+
{
23+
m.Inverse(true);
24+
m.Key(k =>
25+
{
26+
k.Column("OrderId");
27+
k.NotNullable(true);
28+
});
29+
m.Cascade(Mapping.ByCode.Cascade.All.Include(Mapping.ByCode.Cascade.DeleteOrphans));
30+
m.Access(Accessor.NoSetter);
31+
}, m => m.OneToMany());
32+
});
33+
mapper.Class<OrderLine>(rc =>
34+
{
35+
rc.Table("OrderLines");
36+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
37+
rc.Property(x => x.Name);
38+
rc.ManyToOne(x => x.Order, m => m.Column("OrderId"));
39+
});
40+
41+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
42+
}
43+
44+
protected override void OnSetUp()
45+
{
46+
using (var session = OpenSession())
47+
using (var transaction = session.BeginTransaction())
48+
{
49+
var o1 = new Order {Name = "Order 1"};
50+
session.Save(o1);
51+
52+
var o2 = new Order {Name = "Order 2"};
53+
session.Save(o2);
54+
55+
session.Save(new OrderLine {Name = "Order Line 2 - 1", Order = o2});
56+
57+
var o3 = new Order {Name = "Order 3"};
58+
session.Save(o3);
59+
60+
session.Save(new OrderLine {Name = "Order Line 3 - 1", Order = o3});
61+
session.Save(new OrderLine {Name = "Order Line 3 - 2", Order = o3});
62+
63+
var o4 = new Order {Name = "Order 4"};
64+
session.Save(o4);
65+
66+
session.Save(new OrderLine {Name = "Order Line 4 - 1", Order = o4});
67+
session.Save(new OrderLine {Name = "Order Line 4 - 2", Order = o4});
68+
session.Save(new OrderLine {Name = "Order Line 4 - 3", Order = o4});
69+
70+
transaction.Commit();
71+
}
72+
}
73+
74+
protected override void OnTearDown()
75+
{
76+
using (var session = OpenSession())
77+
using (var transaction = session.BeginTransaction())
78+
{
79+
session.Delete("from System.Object");
80+
81+
session.Flush();
82+
transaction.Commit();
83+
}
84+
}
85+
86+
[Test]
87+
public void InnerJoin()
88+
{
89+
//
90+
// select
91+
// order0_.Id as col_0_0_,
92+
// orderlines1_.Id as col_1_0_
93+
// from
94+
// Orders order0_
95+
// inner join
96+
// OrderLines orderlines1_
97+
// on order0_.Id=orderlines1_.OrderId
98+
//
99+
100+
using (var session = OpenSession())
101+
using (session.BeginTransaction())
102+
{
103+
var result = (from o in session.Query<Order>()
104+
from ol in o.OrderLines
105+
select new {OrderId = o.Id, OrderLineId = (Guid?) ol.Id}).ToList();
106+
107+
Assert.AreEqual(6, result.Count);
108+
}
109+
}
110+
111+
[Test]
112+
public void LeftOuterJoin()
113+
{
114+
//
115+
// select
116+
// order0_.Id as col_0_0_,
117+
// orderlines1_.Id as col_1_0_
118+
// from
119+
// Orders order0_
120+
// left outer join
121+
// OrderLines orderlines1_
122+
// on order0_.Id=orderlines1_.OrderId
123+
//
124+
125+
using (var session = OpenSession())
126+
using (session.BeginTransaction())
127+
{
128+
var result = (from o in session.Query<Order>()
129+
from ol in o.OrderLines.DefaultIfEmpty()
130+
select new {OrderId = o.Id, OrderLineId = (Guid?) ol.Id}).ToList();
131+
132+
Assert.AreEqual(7, result.Count);
133+
}
134+
}
135+
136+
[Test]
137+
public void LeftOuterJoinWithInnerRestriction()
138+
{
139+
//
140+
// select
141+
// order0_.Id as col_0_0_,
142+
// orderlines1_.Id as col_1_0_
143+
// from
144+
// Orders order0_
145+
// left outer join
146+
// OrderLines orderlines1_
147+
// on order0_.Id=orderlines1_.OrderId
148+
// and orderlines1_.Name like ('Order Line 3')
149+
//
150+
151+
using (var session = OpenSession())
152+
using (session.BeginTransaction())
153+
{
154+
var result = (from o in session.Query<Order>()
155+
from ol in o.OrderLines.Where(x => x.Name.StartsWith("Order Line 3")).DefaultIfEmpty()
156+
select new {OrderId = o.Id, OrderLineId = (Guid?) ol.Id}).ToList();
157+
158+
Assert.AreEqual(5, result.Count);
159+
}
160+
}
161+
162+
[Test]
163+
public void LeftOuterJoinWithOuterRestriction()
164+
{
165+
//
166+
// select
167+
// order0_.Id as col_0_0_,
168+
// orderlines1_.Id as col_1_0_
169+
// from
170+
// Orders order0_
171+
// left outer join
172+
// OrderLines orderlines1_
173+
// on order0_.Id=orderlines1_.OrderId
174+
// where
175+
// orderlines1_.Name like ('Order Line 3')
176+
//
177+
178+
using (var session = OpenSession())
179+
using (session.BeginTransaction())
180+
{
181+
var result = (from o in session.Query<Order>()
182+
from ol in o.OrderLines.DefaultIfEmpty().Where(x => x.Name.StartsWith("Order Line 3"))
183+
select new {OrderId = o.Id, OrderLineId = (Guid?) ol.Id}).ToList();
184+
185+
Assert.AreEqual(2, result.Count);
186+
}
187+
}
188+
}
189+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH2379
5+
{
6+
public class Order
7+
{
8+
private readonly IEnumerable<OrderLine> _orderLines = new List<OrderLine>();
9+
public virtual Guid Id { get; set; }
10+
public virtual string Name { get; set; }
11+
12+
public virtual IEnumerable<OrderLine> OrderLines
13+
{
14+
get { return _orderLines; }
15+
}
16+
}
17+
18+
public class OrderLine
19+
{
20+
public virtual Guid Id { get; set; }
21+
public virtual string Name { get; set; }
22+
public virtual Order Order { get; set; }
23+
}
24+
}

0 commit comments

Comments
 (0)