Skip to content

Commit b6fd5b3

Browse files
committed
Fix Contains subquery with parameter
1 parent cc13153 commit b6fd5b3

File tree

4 files changed

+179
-7
lines changed

4 files changed

+179
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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;
12+
using System.Linq;
13+
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Mapping.ByCode;
15+
using NUnit.Framework;
16+
using NHibernate.Linq;
17+
18+
namespace NHibernate.Test.NHSpecificTest.GH3218
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class ContainsParameterFixtureAsync : TestCaseMappingByCode
23+
{
24+
protected override HbmMapping GetMappings()
25+
{
26+
var mapper = new ModelMapper();
27+
mapper.Class<Child>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
30+
rc.Property(x => x.Name);
31+
});
32+
mapper.Class<Entity>(rc =>
33+
{
34+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
35+
rc.Property(x => x.Name);
36+
rc.Bag(x => x.List, m => { }, r => r.OneToMany());
37+
});
38+
39+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
40+
}
41+
42+
[Test]
43+
public async Task ContainsOnIdAsync()
44+
{
45+
using (var session = OpenSession())
46+
{
47+
Guid clientId = Guid.NewGuid();
48+
await (session.Query<Entity>().Where(x => x.List.Select(l => l.Id).Contains(clientId)).ToListAsync());
49+
}
50+
}
51+
52+
[Test]
53+
public async Task ContainsOnNameWithInnerSubqueryAsync()
54+
{
55+
using (var session = OpenSession())
56+
{
57+
var clientId = "aa";
58+
await (session.Query<Entity>().Where(x =>
59+
x.List.Where(l => session.Query<Entity>().Any(s => s.Name == l.Name)).Select(l => l.Name)
60+
.Contains(clientId)).ToListAsync());
61+
}
62+
}
63+
64+
[Test]
65+
public async Task ContainsOnEntityAsync()
66+
{
67+
using (var session = OpenSession())
68+
{
69+
var client = await (session.LoadAsync<Child>(Guid.NewGuid()));
70+
await (session.Query<Entity>().Where(x => x.List.Contains(client)).ToListAsync());
71+
}
72+
}
73+
74+
[Test]
75+
public async Task ContainsOnNameAsync()
76+
{
77+
using (var session = OpenSession())
78+
{
79+
var client = "aaa";
80+
await (session.Query<Entity>().Where(x => x.List.Select(l => l.Name).Contains(client)).ToListAsync());
81+
}
82+
}
83+
}
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Mapping.ByCode;
5+
using NUnit.Framework;
6+
7+
namespace NHibernate.Test.NHSpecificTest.GH3218
8+
{
9+
[TestFixture]
10+
public class ContainsParameterFixture : TestCaseMappingByCode
11+
{
12+
protected override HbmMapping GetMappings()
13+
{
14+
var mapper = new ModelMapper();
15+
mapper.Class<Child>(rc =>
16+
{
17+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
18+
rc.Property(x => x.Name);
19+
});
20+
mapper.Class<Entity>(rc =>
21+
{
22+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
23+
rc.Property(x => x.Name);
24+
rc.Bag(x => x.List, m => { }, r => r.OneToMany());
25+
});
26+
27+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
28+
}
29+
30+
[Test]
31+
public void ContainsOnId()
32+
{
33+
using (var session = OpenSession())
34+
{
35+
Guid clientId = Guid.NewGuid();
36+
session.Query<Entity>().Where(x => x.List.Select(l => l.Id).Contains(clientId)).ToList();
37+
}
38+
}
39+
40+
[Test]
41+
public void ContainsOnNameWithInnerSubquery()
42+
{
43+
using (var session = OpenSession())
44+
{
45+
var clientId = "aa";
46+
session.Query<Entity>().Where(x =>
47+
x.List.Where(l => session.Query<Entity>().Any(s => s.Name == l.Name)).Select(l => l.Name)
48+
.Contains(clientId)).ToList();
49+
}
50+
}
51+
52+
[Test]
53+
public void ContainsOnEntity()
54+
{
55+
using (var session = OpenSession())
56+
{
57+
var client = session.Load<Child>(Guid.NewGuid());
58+
session.Query<Entity>().Where(x => x.List.Contains(client)).ToList();
59+
}
60+
}
61+
62+
[Test]
63+
public void ContainsOnName()
64+
{
65+
using (var session = OpenSession())
66+
{
67+
var client = "aaa";
68+
session.Query<Entity>().Where(x => x.List.Select(l => l.Name).Contains(client)).ToList();
69+
}
70+
}
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH3218
5+
{
6+
public class Entity
7+
{
8+
public virtual Guid Id { get; set; }
9+
public virtual string Name { get; set; }
10+
public virtual IList<Child> List { get; set; }
11+
}
12+
13+
public class Child
14+
{
15+
public virtual Guid Id { get; set; }
16+
public virtual string Name { get; set; }
17+
}
18+
}

src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
1+
using System.Collections;
42
using System.Linq;
5-
using System.Linq.Expressions;
63
using NHibernate.Hql.Ast;
4+
using NHibernate.Hql.Ast.ANTLR;
75
using Remotion.Linq.Clauses.ResultOperators;
86

97
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
@@ -38,7 +36,7 @@ public void Process(ContainsResultOperator resultOperator, QueryModelVisitor que
3836
if (itemExpression is HqlParameter)
3937
{
4038
tree.AddWhereClause(tree.TreeBuilder.Equality(
41-
tree.TreeBuilder.Ident(GetFromAlias(tree.Root).AstNode.Text),
39+
GetSelectExpression(tree.Root),
4240
itemExpression));
4341
ProcessAny.Process(tree);
4442
}
@@ -54,9 +52,9 @@ private static HqlRange GetFromRangeClause(HqlTreeNode node)
5452
return node.NodesPreOrder.OfType<HqlRange>().First();
5553
}
5654

57-
private static HqlAlias GetFromAlias(HqlTreeNode node)
55+
private static HqlExpression GetSelectExpression(HqlTreeNode node)
5856
{
59-
return node.NodesPreOrder.Single(n => n is HqlRange).Children.Single(n => n is HqlAlias) as HqlAlias;
57+
return node.NodesPreOrder.First(x => x.AstNode.Type == HqlSqlWalker.SELECT).Children.Single() as HqlExpression;
6058
}
6159

6260
private static bool IsEmptyList(HqlParameter source, VisitorParameters parameters)

0 commit comments

Comments
 (0)