Skip to content

Commit 18667cf

Browse files
Merge 5.3.4 into master
2 parents 2ad61c6 + a129e75 commit 18667cf

File tree

20 files changed

+674
-25
lines changed

20 files changed

+674
-25
lines changed

releasenotes.txt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1-
Build 5.3.3
1+
Build 5.3.4
2+
=============================
3+
4+
Release notes - NHibernate - Version 5.3.4
5+
6+
6 issues were resolved in this release.
7+
8+
** Bug
9+
10+
* #2580 InvalidWithClauseException when join polymorphic entity
11+
* #2559 Regression in caching linq query with ThenFetchMany statement.
12+
* #2549 ApplyFilter does not work on join statements in LINQ
13+
* #2537 Unable to cast "System.Linq.Expressions.UnaryExpression" to "System.Linq.Expressions.LambdaExpression".
14+
15+
** Task
16+
17+
* #2578 Add missing possible breaking changes for #2365
18+
* #2587 Release 5.3.4
19+
20+
As part of releasing 5.3.4, one missing 5.3.0 possible breaking change has been added, about
21+
custom method generators for Linq. See 5.3.0 possible breaking changes.
22+
23+
Build 5.3.3
224
=============================
325

426
Release notes - NHibernate - Version 5.3.3
@@ -135,6 +157,8 @@ Release notes - NHibernate - Version 5.3.0
135157
already exists in the set will now return false.
136158
* Calling `ISet<>.Add` or `ICollection<>.Add` on an uninitialized set mapped as `lazy="true"` with a
137159
transient element that does not override `Equals` method will not initialize the collection.
160+
* Linq custom generators deriving from `BaseHqlGeneratorForMethod` should override the
161+
`TryGetCollectionParameter` method if they have to support parameter lists.
138162

139163
** Bug
140164

src/NHibernate.Test/Async/Linq/ByMethod/JoinTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,13 @@ public async Task CanJoinOnEntityWithSubclassesAsync()
148148
from o2 in db.Animals.Where(x => x.BodyWeight > 50)
149149
select new {o, o2}).Take(1).ToListAsync());
150150
}
151+
152+
[Test(Description = "GH-2580")]
153+
public async Task CanInnerJoinOnSubclassWithBaseTableReferenceInOnClauseAsync()
154+
{
155+
var result = await ((from o in db.Animals
156+
join o2 in db.Mammals on o.BodyWeight equals o2.BodyWeight
157+
select new { o, o2 }).Take(1).ToListAsync());
158+
}
151159
}
152160
}

src/NHibernate.Test/Async/Linq/WhereSubqueryTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,5 +788,30 @@ public async Task NullComparedToMemberInitExpressionInWhereClauseAsync()
788788

789789
Assert.That(result.Count, Is.EqualTo(45));
790790
}
791+
792+
public class Specification<T>
793+
{
794+
private Expression<Func<T, bool>> _expression;
795+
796+
public Specification(Expression<Func<T, bool>> expression)
797+
{
798+
_expression = expression;
799+
}
800+
801+
public static implicit operator Expression<Func<T, bool>>(Specification<T> specification)
802+
{
803+
return specification._expression;
804+
}
805+
}
806+
807+
[Test]
808+
public async Task ImplicitConversionInsideWhereSubqueryExpressionAsync()
809+
{
810+
if (!Dialect.SupportsScalarSubSelects)
811+
Assert.Ignore(Dialect.GetType().Name + " does not support scalar sub-queries");
812+
813+
var spec = new Specification<Order>(x => x.Freight > 1000);
814+
await (db.Orders.Where(o => db.Orders.Where(spec).Any(x => x.OrderId == o.OrderId)).ToListAsync());
815+
}
791816
}
792817
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System.Linq;
12+
using NUnit.Framework;
13+
using NHibernate.Linq;
14+
15+
namespace NHibernate.Test.NHSpecificTest.GH2549
16+
{
17+
using System.Threading.Tasks;
18+
[TestFixture]
19+
public class FixtureAsync : BugTestCase
20+
{
21+
protected override void OnSetUp()
22+
{
23+
using (var s = OpenSession())
24+
using (var t = s.BeginTransaction())
25+
{
26+
s.Save(new Person {Id = 1, Name = "Name"});
27+
s.Save(new Customer {Deleted = false, Name = "Name", Id = 1});
28+
s.Save(new Customer {Deleted = true, Name = "Name", Id = 2});
29+
30+
t.Commit();
31+
}
32+
}
33+
34+
protected override void OnTearDown()
35+
{
36+
using (var s = OpenSession())
37+
using (var t = s.BeginTransaction())
38+
{
39+
s.CreateQuery("delete from System.Object").ExecuteUpdate();
40+
t.Commit();
41+
}
42+
}
43+
44+
[Test]
45+
public async Task EntityJoinFilterLinqAsync()
46+
{
47+
using (var s = OpenSession())
48+
{
49+
var list = await ((from p in s.Query<Person>()
50+
join c in s.Query<Customer>() on p.Name equals c.Name
51+
select p).ToListAsync());
52+
53+
s.EnableFilter("DeletedCustomer").SetParameter("deleted", false);
54+
55+
var filteredList = await ((from p in s.Query<Person>()
56+
join c in s.Query<Customer>() on p.Name equals c.Name
57+
select p).ToListAsync());
58+
59+
Assert.That(list, Has.Count.EqualTo(2));
60+
Assert.That(filteredList, Has.Count.EqualTo(1));
61+
}
62+
}
63+
64+
[Test]
65+
public async Task EntityJoinFilterQueryOverAsync()
66+
{
67+
using (var s = OpenSession())
68+
{
69+
Customer c = null;
70+
Person p = null;
71+
var list = await (s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).ListAsync());
72+
73+
s.EnableFilter("DeletedCustomer").SetParameter("deleted", false);
74+
75+
var filteredList = await (s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).ListAsync());
76+
77+
Assert.That(list, Has.Count.EqualTo(2));
78+
Assert.That(filteredList, Has.Count.EqualTo(1));
79+
}
80+
}
81+
}
82+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System.Linq;
12+
using NHibernate.Cfg.MappingSchema;
13+
using NHibernate.Linq;
14+
using NHibernate.Mapping.ByCode;
15+
using NUnit.Framework;
16+
17+
namespace NHibernate.Test.NHSpecificTest.GH2559
18+
{
19+
using System.Threading.Tasks;
20+
[TestFixture]
21+
public class ByCodeFixtureAsync : TestCaseMappingByCode
22+
{
23+
protected override HbmMapping GetMappings()
24+
{
25+
var mapper = new ModelMapper();
26+
mapper.Class<Person>(rc =>
27+
{
28+
rc.Id(x => x.Id, m => m.Generator(Generators.Guid));
29+
rc.Property(x => x.Name);
30+
rc.Property(x => x.Age);
31+
rc.Set(
32+
x => x.Children,
33+
colMap =>
34+
{
35+
colMap.Inverse(true);
36+
colMap.Cascade(Mapping.ByCode.Cascade.DeleteOrphans);
37+
colMap.Cache(c => c.Usage(CacheUsage.ReadWrite));
38+
},
39+
rel => rel.OneToMany());
40+
rc.Set(
41+
x => x.Cars,
42+
colMap =>
43+
{
44+
colMap.Inverse(true);
45+
colMap.Cascade(Mapping.ByCode.Cascade.DeleteOrphans);
46+
colMap.Cache(c => c.Usage(CacheUsage.ReadWrite));
47+
},
48+
rel => rel.OneToMany());
49+
rc.Cache(c => c.Usage(CacheUsage.ReadWrite));
50+
});
51+
mapper.Class<Child>(ch =>
52+
{
53+
ch.Id(x => x.Id, m => m.Generator(Generators.Guid));
54+
ch.Property(x => x.Name);
55+
ch.ManyToOne(c => c.Parent);
56+
57+
ch.Set(
58+
x => x.Pets,
59+
colMap =>
60+
{
61+
colMap.Inverse(true);
62+
colMap.Cascade(Mapping.ByCode.Cascade.DeleteOrphans);
63+
colMap.Cache(c => c.Usage(CacheUsage.ReadWrite));
64+
},
65+
rel => rel.OneToMany());
66+
67+
ch.Cache(c => c.Usage(CacheUsage.ReadWrite));
68+
});
69+
mapper.Class<Pet>(ch =>
70+
{
71+
ch.Id(x => x.Id, m => m.Generator(Generators.Guid));
72+
ch.Property(x => x.Name);
73+
ch.ManyToOne(c => c.Owner);
74+
75+
ch.Cache(c => c.Usage(CacheUsage.ReadWrite));
76+
});
77+
mapper.Class<Car>(ch =>
78+
{
79+
ch.Id(x => x.Id, m => m.Generator(Generators.Guid));
80+
ch.Property(x => x.Name);
81+
ch.ManyToOne(c => c.Owner);
82+
83+
ch.Cache(c => c.Usage(CacheUsage.ReadWrite));
84+
});
85+
86+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
87+
}
88+
89+
protected override void OnSetUp()
90+
{
91+
using (var session = OpenSession())
92+
using (var transaction = session.BeginTransaction())
93+
{
94+
var person = new Person { Name = "Person 1", Age = 18 };
95+
96+
var car1 = new Car { Name = "Car1", Owner = person };
97+
var car2 = new Car { Name = "Car2", Owner = person };
98+
session.Save(car1);
99+
session.Save(car2);
100+
101+
session.Save(person);
102+
transaction.Commit();
103+
}
104+
}
105+
106+
protected override void OnTearDown()
107+
{
108+
using (var session = OpenSession())
109+
using (var transaction = session.BeginTransaction())
110+
{
111+
session.CreateQuery("delete from Pet").ExecuteUpdate();
112+
session.CreateQuery("delete from Child").ExecuteUpdate();
113+
session.CreateQuery("delete from Car").ExecuteUpdate();
114+
session.CreateQuery("delete from Person").ExecuteUpdate();
115+
transaction.Commit();
116+
}
117+
}
118+
119+
[Test]
120+
public async Task TestQueryCachingWithThenFetchManyAsync()
121+
{
122+
Person dbPerson;
123+
Person cachePerson;
124+
using (var session = OpenSession())
125+
using (var transaction = session.BeginTransaction())
126+
{
127+
var query =
128+
session
129+
.Query<Person>()
130+
.FetchMany(p => p.Children)
131+
.ThenFetchMany(ch => ch.Pets)
132+
.FetchMany(p => p.Cars) as IQueryable<Person>;
133+
134+
query = query.WithOptions(opt =>
135+
opt.SetCacheable(true)
136+
.SetCacheMode(CacheMode.Normal)
137+
.SetCacheRegion("Long_Cache"));
138+
139+
dbPerson = (await (query.ToListAsync())).First(); // First time the result will be cached
140+
cachePerson = (await (query.ToListAsync())).First();
141+
142+
await (transaction.CommitAsync());
143+
}
144+
145+
Assert.That(NHibernateUtil.IsInitialized(dbPerson.Cars), Is.True);
146+
Assert.That(NHibernateUtil.IsInitialized(cachePerson.Cars), Is.True);
147+
Assert.That(dbPerson.Cars, Has.Count.EqualTo(2));
148+
Assert.That(cachePerson.Cars, Has.Count.EqualTo(2));
149+
150+
Assert.That(NHibernateUtil.IsInitialized(dbPerson.Children), Is.True);
151+
Assert.That(NHibernateUtil.IsInitialized(cachePerson.Children), Is.True);
152+
Assert.That(dbPerson.Children, Has.Count.EqualTo(0));
153+
Assert.That(cachePerson.Children, Has.Count.EqualTo(0));
154+
}
155+
}
156+
}

src/NHibernate.Test/Linq/ByMethod/JoinTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,13 @@ public void CanJoinOnEntityWithSubclasses()
137137
from o2 in db.Animals.Where(x => x.BodyWeight > 50)
138138
select new {o, o2}).Take(1).ToList();
139139
}
140+
141+
[Test(Description = "GH-2580")]
142+
public void CanInnerJoinOnSubclassWithBaseTableReferenceInOnClause()
143+
{
144+
var result = (from o in db.Animals
145+
join o2 in db.Mammals on o.BodyWeight equals o2.BodyWeight
146+
select new { o, o2 }).Take(1).ToList();
147+
}
140148
}
141149
}

src/NHibernate.Test/Linq/WhereSubqueryTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,5 +956,30 @@ public void NullComparedToMemberInitExpressionInWhereClause()
956956

957957
Assert.That(result.Count, Is.EqualTo(45));
958958
}
959+
960+
public class Specification<T>
961+
{
962+
private Expression<Func<T, bool>> _expression;
963+
964+
public Specification(Expression<Func<T, bool>> expression)
965+
{
966+
_expression = expression;
967+
}
968+
969+
public static implicit operator Expression<Func<T, bool>>(Specification<T> specification)
970+
{
971+
return specification._expression;
972+
}
973+
}
974+
975+
[Test]
976+
public void ImplicitConversionInsideWhereSubqueryExpression()
977+
{
978+
if (!Dialect.SupportsScalarSubSelects)
979+
Assert.Ignore(Dialect.GetType().Name + " does not support scalar sub-queries");
980+
981+
var spec = new Specification<Order>(x => x.Freight > 1000);
982+
db.Orders.Where(o => db.Orders.Where(spec).Any(x => x.OrderId == o.OrderId)).ToList();
983+
}
959984
}
960985
}

0 commit comments

Comments
 (0)