Skip to content

Commit f257331

Browse files
committed
Apply filters for entity joins
1 parent 7530a25 commit f257331

File tree

6 files changed

+159
-39
lines changed

6 files changed

+159
-39
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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 EntityJoinFilterAsync()
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+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System.Linq;
2+
using NUnit.Framework;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH2549
5+
{
6+
[TestFixture]
7+
public class Fixture : BugTestCase
8+
{
9+
protected override void OnSetUp()
10+
{
11+
using (var s = OpenSession())
12+
using (var t = s.BeginTransaction())
13+
{
14+
s.Save(new Person {Id = 1, Name = "Name"});
15+
s.Save(new Customer {Deleted = false, Name = "Name", Id = 1});
16+
s.Save(new Customer {Deleted = true, Name = "Name", Id = 2});
17+
18+
t.Commit();
19+
}
20+
}
21+
22+
protected override void OnTearDown()
23+
{
24+
using (var s = OpenSession())
25+
using (var t = s.BeginTransaction())
26+
{
27+
s.CreateQuery("delete from System.Object").ExecuteUpdate();
28+
t.Commit();
29+
}
30+
}
31+
32+
[Test]
33+
public void EntityJoinFilter()
34+
{
35+
using (var s = OpenSession())
36+
{
37+
var list = (from p in s.Query<Person>()
38+
join c in s.Query<Customer>() on p.Name equals c.Name
39+
select p).ToList();
40+
41+
s.EnableFilter("DeletedCustomer").SetParameter("deleted", false);
42+
43+
var filteredList = (from p in s.Query<Person>()
44+
join c in s.Query<Customer>() on p.Name equals c.Name
45+
select p).ToList();
46+
47+
Assert.That(list, Has.Count.EqualTo(2));
48+
Assert.That(filteredList, Has.Count.EqualTo(1));
49+
}
50+
}
51+
}
52+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
3+
namespace="NHibernate.Test.NHSpecificTest.GH2549" >
4+
5+
<class name="Customer">
6+
<id name="Id">
7+
<generator class="assigned" />
8+
</id>
9+
<property name="Name" />
10+
<property name="Deleted" type="Boolean" not-null="true" />
11+
12+
<filter name="DeletedCustomer" condition="Deleted = :deleted" />
13+
</class>
14+
15+
<class name="Person">
16+
<id name="Id">
17+
<generator class="assigned" />
18+
</id>
19+
<property name="Name" />
20+
</class>
21+
22+
<filter-def name="DeletedCustomer">
23+
<filter-param name="deleted" type="Boolean"/>
24+
</filter-def>
25+
26+
</hibernate-mapping>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH2549
2+
{
3+
public class Customer
4+
{
5+
public virtual int Id { get; set; }
6+
public virtual bool Deleted { get; set; }
7+
public virtual string Name { get; set; }
8+
}
9+
10+
public class Person
11+
{
12+
public virtual int Id { get; set; }
13+
public virtual string Name { get; set; }
14+
}
15+
}

src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinFromElement.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public EntityJoinFromElement(FromClause fromClause, IQueryable entityPersister,
1818
JoinSequence = new EntityJoinJoinSequenceImpl(
1919
SessionFactoryHelper.Factory,
2020
entityType,
21-
entityPersister.TableName,
2221
tableAlias,
2322
joinType);
2423

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using NHibernate.Engine;
43
using NHibernate.SqlCommand;
54
using NHibernate.Type;
@@ -8,44 +7,9 @@ namespace NHibernate.Hql.Ast.ANTLR.Tree
87
{
98
class EntityJoinJoinSequenceImpl : JoinSequence
109
{
11-
private readonly EntityType _entityType;
12-
private readonly string _tableName;
13-
private readonly string _tableAlias;
14-
private readonly JoinType _joinType;
15-
16-
public EntityJoinJoinSequenceImpl(ISessionFactoryImplementor factory, EntityType entityType, string tableName, string tableAlias, JoinType joinType):base(factory)
10+
public EntityJoinJoinSequenceImpl(ISessionFactoryImplementor factory, EntityType entityType, string tableAlias, JoinType joinType):base(factory)
1711
{
18-
_entityType = entityType;
19-
_tableName = tableName;
20-
_tableAlias = tableAlias;
21-
_joinType = joinType;
22-
}
23-
24-
internal override JoinFragment ToJoinFragment(
25-
IDictionary<string, IFilter> enabledFilters,
26-
bool includeExtraJoins,
27-
SqlString withClauseFragment,
28-
string withClauseJoinAlias,
29-
string withRootAlias)
30-
{
31-
var joinFragment = new ANSIJoinFragment();
32-
33-
var on = withClauseFragment ?? SqlString.Empty;
34-
//Note: filters logic commented due to following issues
35-
//1) Original code is non functional as SqlString is immutable and so all Append results are lost. Correct code would look like: on = on.Append(filters);
36-
//2) Also it seems GetOnCondition always returns empty string for entity join (as IsReferenceToPrimaryKey is always true).
37-
// So if filters for entity join really make sense we need to inline GetOnCondition part that retrieves filters
38-
// var filters = _entityType.GetOnCondition(_tableAlias, Factory, enabledFilters);
39-
// if (!string.IsNullOrEmpty(filters))
40-
// {
41-
// on.Append(" and ").Append(filters);
42-
// }
43-
joinFragment.AddJoin(_tableName, _tableAlias, Array.Empty<string>(), Array.Empty<string>(), _joinType, on);
44-
if (includeExtraJoins)
45-
{
46-
AddExtraJoins(joinFragment, _tableAlias, _entityType.GetAssociatedJoinable(Factory), _joinType == JoinType.InnerJoin);
47-
}
48-
return joinFragment;
12+
AddJoin(entityType, tableAlias, joinType, Array.Empty<string>());
4913
}
5014
}
5115
}

0 commit comments

Comments
 (0)