Skip to content

Commit 2abfeb9

Browse files
committed
Proper support for IN clause for composite properties
1 parent b734d00 commit 2abfeb9

18 files changed

+503
-252
lines changed

src/NHibernate.Test/Async/CompositeId/ClassWithCompositeIdFixture.cs

Lines changed: 129 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ protected override string[] Mappings
3737
get { return new string[] {"CompositeId.ClassWithCompositeId.hbm.xml"}; }
3838
}
3939

40-
protected override bool AppliesTo(Dialect.Dialect dialect)
41-
{
42-
return !(dialect is Dialect.FirebirdDialect); // Firebird has no CommandTimeout, and locks up during the tear-down of this fixture
43-
}
44-
4540
protected override void OnSetUp()
4641
{
4742
id = new Id("stringKey", 3, firstDateTime);
@@ -51,9 +46,11 @@ protected override void OnSetUp()
5146
protected override void OnTearDown()
5247
{
5348
using (ISession s = Sfi.OpenSession())
49+
using (var t = s.BeginTransaction())
5450
{
5551
s.Delete("from ClassWithCompositeId");
5652
s.Flush();
53+
t.Commit();
5754
}
5855
}
5956

@@ -239,5 +236,132 @@ public async Task HqlAsync()
239236
Assert.AreEqual(1, results.Count);
240237
}
241238
}
239+
240+
[Test]
241+
public async Task QueryOverInClauseAsync()
242+
{
243+
if(!Dialect.SupportsRowValueConstructorSyntaxInInList)
244+
Assert.Ignore();
245+
246+
// insert the new objects
247+
using (ISession s = OpenSession())
248+
using (ITransaction t = s.BeginTransaction())
249+
{
250+
await (s.SaveAsync(new ClassWithCompositeId(id) {OneProperty = 5}));
251+
await (s.SaveAsync(new ClassWithCompositeId(secondId) {OneProperty = 10}));
252+
await (s.SaveAsync(new ClassWithCompositeId(new Id(id.KeyString, id.GetKeyShort(), secondId.KeyDateTime))));
253+
254+
await (t.CommitAsync());
255+
}
256+
257+
using (var s = OpenSession())
258+
{
259+
var results = await (s.QueryOver<ClassWithCompositeId>().WhereRestrictionOn(p => p.Id).IsIn(new[] {id, secondId}).ListAsync());
260+
Assert.That(results.Count, Is.EqualTo(2));
261+
}
262+
}
263+
264+
[Test]
265+
public async Task HqlInClauseAsync()
266+
{
267+
if (!Dialect.SupportsRowValueConstructorSyntaxInInList)
268+
Assert.Ignore();
269+
270+
// insert the new objects
271+
using (ISession s = OpenSession())
272+
using (ITransaction t = s.BeginTransaction())
273+
{
274+
await (s.SaveAsync(new ClassWithCompositeId(id) {OneProperty = 5}));
275+
await (s.SaveAsync(new ClassWithCompositeId(secondId) {OneProperty = 10}));
276+
await (s.SaveAsync(new ClassWithCompositeId(new Id(id.KeyString, id.GetKeyShort(), secondId.KeyDateTime))));
277+
278+
await (t.CommitAsync());
279+
}
280+
281+
using (var s = OpenSession())
282+
{
283+
var results = await (s.CreateQuery("from ClassWithCompositeId x where x.Id in (:id1, :id2)")
284+
.SetParameter("id1", id)
285+
.SetParameter("id2", secondId)
286+
.ListAsync<ClassWithCompositeId>());
287+
Assert.That(results.Count, Is.EqualTo(2));
288+
}
289+
}
290+
291+
[Test]
292+
public async Task QueryOverInClauseSubqueryAsync()
293+
{
294+
if (!TestDialect.SupportsRowValueConstructorSyntax)
295+
{
296+
Assert.Ignore();
297+
}
298+
299+
// insert the new objects
300+
using (ISession s = OpenSession())
301+
using (ITransaction t = s.BeginTransaction())
302+
{
303+
await (s.SaveAsync(new ClassWithCompositeId(id) {OneProperty = 5}));
304+
await (s.SaveAsync(new ClassWithCompositeId(secondId) {OneProperty = 10}));
305+
await (s.SaveAsync(new ClassWithCompositeId(new Id(id.KeyString, id.GetKeyShort(), secondId.KeyDateTime))));
306+
307+
await (t.CommitAsync());
308+
}
309+
310+
using (var s = OpenSession())
311+
{
312+
var results = await (s.QueryOver<ClassWithCompositeId>().WithSubquery.WhereProperty(p => p.Id).In(QueryOver.Of<ClassWithCompositeId>().Where(p => p.Id.KeyString == id.KeyString).Select(p => p.Id)).ListAsync());
313+
Assert.That(results.Count, Is.EqualTo(2));
314+
}
315+
}
316+
317+
[Test]
318+
public async Task HqlInClauseSubqueryAsync()
319+
{
320+
if (!TestDialect.SupportsRowValueConstructorSyntax)
321+
Assert.Ignore();
322+
323+
// insert the new objects
324+
using (ISession s = OpenSession())
325+
using (ITransaction t = s.BeginTransaction())
326+
{
327+
await (s.SaveAsync(new ClassWithCompositeId(id) {OneProperty = 5}));
328+
await (s.SaveAsync(new ClassWithCompositeId(secondId) {OneProperty = 10}));
329+
await (s.SaveAsync(new ClassWithCompositeId(new Id(id.KeyString, id.GetKeyShort(), secondId.KeyDateTime))));
330+
331+
await (t.CommitAsync());
332+
}
333+
334+
using (var s = OpenSession())
335+
{
336+
var results = await (s.CreateQuery("from ClassWithCompositeId x where x.Id in (select s.Id from ClassWithCompositeId s where s.Id.KeyString = :keyString)")
337+
.SetParameter("keyString", id.KeyString).ListAsync());
338+
Assert.That(results.Count, Is.EqualTo(2));
339+
}
340+
}
341+
342+
[Test]
343+
public async Task HqlInClauseSubquery_ForEntityAsync()
344+
{
345+
if (!TestDialect.SupportsRowValueConstructorSyntax)
346+
Assert.Ignore();
347+
348+
// insert the new objects
349+
using (ISession s = OpenSession())
350+
using (ITransaction t = s.BeginTransaction())
351+
{
352+
await (s.SaveAsync(new ClassWithCompositeId(id) {OneProperty = 5}));
353+
await (s.SaveAsync(new ClassWithCompositeId(secondId) {OneProperty = 10}));
354+
await (s.SaveAsync(new ClassWithCompositeId(new Id(id.KeyString, id.GetKeyShort(), secondId.KeyDateTime))));
355+
356+
await (t.CommitAsync());
357+
}
358+
359+
using (var s = OpenSession())
360+
{
361+
var results = await (s.CreateQuery("from ClassWithCompositeId x where x in (select s from ClassWithCompositeId s where s.Id.KeyString = :keyString)")
362+
.SetParameter("keyString", id.KeyString).ListAsync());
363+
Assert.That(results.Count, Is.EqualTo(2));
364+
}
365+
}
242366
}
243367
}

src/NHibernate.Test/Async/Criteria/CriteriaQueryTest.cs

Lines changed: 26 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -288,122 +288,57 @@ public async Task SubselectWithComponentAsync()
288288
await (t.CommitAsync());
289289
}
290290

291-
if (TestDialect.SupportsOperatorAll)
291+
//Note: It might require separate test dialect flag like SupportsRowValueConstructorWithOperatorAll
292+
if (TestDialect.SupportsOperatorAll && TestDialect.SupportsRowValueConstructorSyntax)
292293
{
293294
using (ISession session = OpenSession())
294-
using (ITransaction t = session.BeginTransaction())
295295
{
296-
try
297-
{
298-
await (session.CreateCriteria<Student>()
296+
await (session.CreateCriteria<Student>()
299297
.Add(Subqueries.PropertyEqAll("CityState", dc))
300298
.ListAsync());
301-
302-
Assert.Fail("should have failed because cannot compare subquery results with multiple columns");
303-
}
304-
catch (QueryException)
305-
{
306-
// expected
307-
}
308-
await (t.RollbackAsync());
309299
}
310-
}
311300

312-
if (TestDialect.SupportsOperatorAll)
313-
{
314301
using (ISession session = OpenSession())
315-
using (ITransaction t = session.BeginTransaction())
316302
{
317-
try
318-
{
319-
await (session.CreateCriteria<Student>()
303+
await (session.CreateCriteria<Student>()
320304
.Add(Property.ForName("CityState").EqAll(dc))
321305
.ListAsync());
322-
323-
Assert.Fail("should have failed because cannot compare subquery results with multiple columns");
324-
}
325-
catch (QueryException)
326-
{
327-
// expected
328-
}
329-
finally
330-
{
331-
await (t.RollbackAsync());
332-
}
333306
}
334307
}
335308

336-
using (ISession session = OpenSession())
337-
using (ITransaction t = session.BeginTransaction())
309+
if (TestDialect.SupportsRowValueConstructorSyntax)
338310
{
339-
try
311+
using (ISession session = OpenSession())
340312
{
313+
341314
await (session.CreateCriteria<Student>()
342-
.Add(Subqueries.In(odessaWa, dc))
343-
.ListAsync());
344-
345-
Assert.Fail("should have failed because cannot compare subquery results with multiple columns");
346-
}
347-
catch (NHibernate.Exceptions.GenericADOException)
348-
{
349-
// expected
350-
}
351-
finally
352-
{
353-
await (t.RollbackAsync());
315+
.Add(Subqueries.In(odessaWa, dc))
316+
.ListAsync());
354317
}
355-
}
356-
357-
using (ISession session = OpenSession())
358-
using (ITransaction t = session.BeginTransaction())
359-
{
360-
DetachedCriteria dc2 = DetachedCriteria.For<Student>("st1")
361-
.Add(Property.ForName("st1.CityState").EqProperty("st2.CityState"))
362-
.SetProjection(Property.ForName("CityState"));
363-
364-
try
318+
319+
using (ISession session = OpenSession())
365320
{
321+
DetachedCriteria dc2 = DetachedCriteria.For<Student>("st1")
322+
.Add(Property.ForName("st1.CityState").EqProperty("st2.CityState"))
323+
.SetProjection(Property.ForName("CityState"));
366324
await (session.CreateCriteria<Student>("st2")
367-
.Add( Subqueries.Eq(odessaWa, dc2))
368-
.ListAsync());
369-
Assert.Fail("should have failed because cannot compare subquery results with multiple columns");
370-
}
371-
catch (NHibernate.Exceptions.GenericADOException)
372-
{
373-
// expected
374-
}
375-
finally
376-
{
377-
await (t.RollbackAsync());
325+
.Add( Subqueries.Eq(odessaWa, dc2))
326+
.ListAsync());
378327
}
379-
}
380-
381-
using (ISession session = OpenSession())
382-
using (ITransaction t = session.BeginTransaction())
383-
{
384-
DetachedCriteria dc3 = DetachedCriteria.For<Student>("st")
385-
.CreateCriteria("Enrolments")
386-
.CreateCriteria("Course")
387-
.Add(Property.ForName("Description").Eq("Hibernate Training"))
388-
.SetProjection(Property.ForName("st.CityState"));
389-
try
328+
329+
using (ISession session = OpenSession())
390330
{
331+
DetachedCriteria dc3 = DetachedCriteria.For<Student>("st")
332+
.CreateCriteria("Enrolments")
333+
.CreateCriteria("Course")
334+
.Add(Property.ForName("Description").Eq("Hibernate Training"))
335+
.SetProjection(Property.ForName("st.CityState"));
391336
await (session.CreateCriteria<Enrolment>("e")
392-
.Add(Subqueries.Eq(odessaWa, dc3))
393-
.ListAsync());
394-
395-
Assert.Fail("should have failed because cannot compare subquery results with multiple columns");
396-
}
397-
catch (NHibernate.Exceptions.GenericADOException)
398-
{
399-
// expected
400-
}
401-
finally
402-
{
403-
await (t.RollbackAsync());
337+
.Add(Subqueries.Eq(odessaWa, dc3))
338+
.ListAsync());
404339
}
405340
}
406-
341+
407342
using (ISession session = OpenSession())
408343
using (ITransaction t = session.BeginTransaction())
409344
{

0 commit comments

Comments
 (0)