diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH0000/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH0000/Fixture.cs
index 9e6d31db053..29c4aabe5cc 100644
--- a/src/NHibernate.Test/Async/NHSpecificTest/GH0000/Fixture.cs
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH0000/Fixture.cs
@@ -41,7 +41,7 @@ protected override void OnTearDown()
// The HQL delete does all the job inside the database without loading the entities, but it does
// not handle delete order for avoiding violating constraints if any. Use
// session.Delete("from System.Object");
- // instead if in need of having NHbernate ordering the deletes, but this will cause
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
// loading the entities in the session.
session.CreateQuery("delete from System.Object").ExecuteUpdate();
diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1994/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1994/Fixture.cs
new file mode 100644
index 00000000000..34b02db20e2
--- /dev/null
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1994/Fixture.cs
@@ -0,0 +1,117 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by AsyncGenerator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+
+using System.Linq;
+using NHibernate.Dialect;
+using NHibernate.Linq;
+using NHibernate.Transform;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.GH1994
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class FixtureAsync : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var a = new Asset();
+ a.Documents.Add(new Document { IsDeleted = true });
+ a.Documents.Add(new Document { IsDeleted = false });
+
+ session.Save(a);
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ // The HQL delete does all the job inside the database without loading the entities, but it does
+ // not handle delete order for avoiding violating constraints if any. Use
+ // session.Delete("from System.Object");
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
+ // loading the entities in the session.
+
+ session.Delete("from System.Object");
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public async Task TestUnfilteredLinqQueryAsync()
+ {
+ using (var s = OpenSession())
+ {
+ var query = await (s.Query()
+ .FetchMany(x => x.Documents)
+ .ToListAsync());
+
+ Assert.That(query.Count, Is.EqualTo(1), "unfiltered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(2), "unfiltered asset documents");
+ }
+ }
+
+ [Test]
+ public async Task TestFilteredByWhereCollectionLinqQueryAsync()
+ {
+ if(Dialect is PostgreSQLDialect)
+ Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
+
+ using (var s = OpenSession())
+ {
+ var query = await (s.Query()
+ .FetchMany(x => x.DocumentsFiltered)
+ .ToListAsync());
+
+ Assert.That(query.Count, Is.EqualTo(1), "unfiltered assets");
+ Assert.That(query[0].DocumentsFiltered.Count, Is.EqualTo(1), "unfiltered asset documents");
+ }
+ }
+
+ [Test]
+ public async Task TestFilteredLinqQueryAsync()
+ {
+ using (var s = OpenSession())
+ {
+ s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
+ var query = await (s.Query()
+ .FetchMany(x => x.Documents)
+ .ToListAsync());
+
+ Assert.That(query.Count, Is.EqualTo(1), "filtered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
+ }
+ }
+
+ [Test]
+ public async Task TestFilteredQueryOverAsync()
+ {
+ using (var s = OpenSession())
+ {
+ s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
+
+ var query = await (s.QueryOver()
+ .Fetch(SelectMode.Fetch, x => x.Documents)
+ .TransformUsing(Transformers.DistinctRootEntity)
+ .ListAsync());
+
+ Assert.That(query.Count, Is.EqualTo(1), "filtered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH0000/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH0000/Fixture.cs
index 4a8ce621f17..58c728c7028 100644
--- a/src/NHibernate.Test/NHSpecificTest/GH0000/Fixture.cs
+++ b/src/NHibernate.Test/NHSpecificTest/GH0000/Fixture.cs
@@ -29,7 +29,7 @@ protected override void OnTearDown()
// The HQL delete does all the job inside the database without loading the entities, but it does
// not handle delete order for avoiding violating constraints if any. Use
// session.Delete("from System.Object");
- // instead if in need of having NHbernate ordering the deletes, but this will cause
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
// loading the entities in the session.
session.CreateQuery("delete from System.Object").ExecuteUpdate();
diff --git a/src/NHibernate.Test/NHSpecificTest/GH1994/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH1994/Entity.cs
new file mode 100644
index 00000000000..44f9719be0b
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH1994/Entity.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace NHibernate.Test.NHSpecificTest.GH1994
+{
+ public class Base
+ {
+ public virtual Guid Key { get; set; }
+
+ public virtual bool IsDeleted { get; set; }
+ }
+
+ public class Asset : Base
+ {
+ public virtual ISet Documents { get; set; } = new HashSet();
+ public virtual ISet DocumentsFiltered { get; set; } = new HashSet();
+ }
+
+ public class Document : Base
+ {
+ public virtual ISet Assets { get; set; } = new HashSet();
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH1994/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH1994/Fixture.cs
new file mode 100644
index 00000000000..aa0835d9a17
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH1994/Fixture.cs
@@ -0,0 +1,106 @@
+using System.Linq;
+using NHibernate.Dialect;
+using NHibernate.Linq;
+using NHibernate.Transform;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.GH1994
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var a = new Asset();
+ a.Documents.Add(new Document { IsDeleted = true });
+ a.Documents.Add(new Document { IsDeleted = false });
+
+ session.Save(a);
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ // The HQL delete does all the job inside the database without loading the entities, but it does
+ // not handle delete order for avoiding violating constraints if any. Use
+ // session.Delete("from System.Object");
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
+ // loading the entities in the session.
+
+ session.Delete("from System.Object");
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public void TestUnfilteredLinqQuery()
+ {
+ using (var s = OpenSession())
+ {
+ var query = s.Query()
+ .FetchMany(x => x.Documents)
+ .ToList();
+
+ Assert.That(query.Count, Is.EqualTo(1), "unfiltered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(2), "unfiltered asset documents");
+ }
+ }
+
+ [Test]
+ public void TestFilteredByWhereCollectionLinqQuery()
+ {
+ if(Dialect is PostgreSQLDialect)
+ Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
+
+ using (var s = OpenSession())
+ {
+ var query = s.Query()
+ .FetchMany(x => x.DocumentsFiltered)
+ .ToList();
+
+ Assert.That(query.Count, Is.EqualTo(1), "unfiltered assets");
+ Assert.That(query[0].DocumentsFiltered.Count, Is.EqualTo(1), "unfiltered asset documents");
+ }
+ }
+
+ [Test]
+ public void TestFilteredLinqQuery()
+ {
+ using (var s = OpenSession())
+ {
+ s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
+ var query = s.Query()
+ .FetchMany(x => x.Documents)
+ .ToList();
+
+ Assert.That(query.Count, Is.EqualTo(1), "filtered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
+ }
+ }
+
+ [Test]
+ public void TestFilteredQueryOver()
+ {
+ using (var s = OpenSession())
+ {
+ s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
+
+ var query = s.QueryOver()
+ .Fetch(SelectMode.Fetch, x => x.Documents)
+ .TransformUsing(Transformers.DistinctRootEntity)
+ .List();
+
+ Assert.That(query.Count, Is.EqualTo(1), "filtered assets");
+ Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH1994/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH1994/Mappings.hbm.xml
new file mode 100644
index 00000000000..57a58acefa8
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH1994/Mappings.hbm.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NHibernate/Async/Persister/Collection/AbstractCollectionPersister.cs b/src/NHibernate/Async/Persister/Collection/AbstractCollectionPersister.cs
index eb15d667603..8577bab32a2 100644
--- a/src/NHibernate/Async/Persister/Collection/AbstractCollectionPersister.cs
+++ b/src/NHibernate/Async/Persister/Collection/AbstractCollectionPersister.cs
@@ -39,6 +39,7 @@ namespace NHibernate.Persister.Collection
{
using System.Threading.Tasks;
using System.Threading;
+
public abstract partial class AbstractCollectionPersister : ICollectionMetadata, ISqlLoadableCollection,
IPostInsertIdentityPersister, ISupportSelectModeJoinable, ICompositeKeyPostInsertIdentityPersister
{
diff --git a/src/NHibernate/Loader/BasicLoader.cs b/src/NHibernate/Loader/BasicLoader.cs
index 2d3ddafd877..97c0781da4b 100644
--- a/src/NHibernate/Loader/BasicLoader.cs
+++ b/src/NHibernate/Loader/BasicLoader.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
@@ -50,7 +51,7 @@ protected override void PostInstantiate()
{
bagCount++;
}
- collectionDescriptors[i] = new GeneratedCollectionAliases(collectionPersisters[i], collectionSuffixes[i]);
+ collectionDescriptors[i] = new GeneratedCollectionAliases(GetCollectionUserProvidedAlias(i), collectionPersisters[i], collectionSuffixes[i]);
}
}
else
@@ -66,6 +67,11 @@ protected override void PostInstantiate()
}
}
+ protected virtual IDictionary GetCollectionUserProvidedAlias(int index)
+ {
+ return null;
+ }
+
private static bool IsBag(ICollectionPersister collectionPersister)
{
var type = collectionPersister.CollectionType.GetType();
diff --git a/src/NHibernate/Loader/Custom/ColumnCollectionAliases.cs b/src/NHibernate/Loader/Custom/ColumnCollectionAliases.cs
index 1b8a7f2f2d5..3ff5fd9a3ba 100644
--- a/src/NHibernate/Loader/Custom/ColumnCollectionAliases.cs
+++ b/src/NHibernate/Loader/Custom/ColumnCollectionAliases.cs
@@ -1,7 +1,5 @@
-using System.Collections;
using System.Collections.Generic;
using NHibernate.Persister.Collection;
-using NHibernate.Util;
namespace NHibernate.Loader.Custom
{
@@ -15,19 +13,13 @@ public class ColumnCollectionAliases : ICollectionAliases
private readonly string[] indexAliases;
private readonly string[] elementAliases;
private readonly string identifierAlias;
- private readonly IDictionary userProvidedAliases;
public ColumnCollectionAliases(IDictionary userProvidedAliases, ISqlLoadableCollection persister)
{
- this.userProvidedAliases = userProvidedAliases;
-
- keyAliases = GetUserProvidedAliases("key", persister.KeyColumnNames);
-
- indexAliases = GetUserProvidedAliases("index", persister.IndexColumnNames);
-
- elementAliases = GetUserProvidedAliases("element", persister.ElementColumnNames);
-
- identifierAlias = GetUserProvidedAlias("id", persister.IdentifierColumnName);
+ keyAliases = GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropKey, persister.KeyColumnNames);
+ indexAliases = GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropIndex, persister.IndexColumnNames);
+ elementAliases = GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropElement, persister.ElementColumnNames);
+ identifierAlias = GetUserProvidedAlias(userProvidedAliases, CollectionPersister.PropId, persister.IdentifierColumnName);
}
///
@@ -90,30 +82,24 @@ private static string Join(string[] aliases)
: string.Join(", ", aliases);
}
- private string[] GetUserProvidedAliases(string propertyPath, string[] defaultAliases)
+ private static string[] GetUserProvidedAliases(IDictionary userProvidedAliases, string propertyPath, string[] defaultAliases)
{
- string[] result;
- if (!userProvidedAliases.TryGetValue(propertyPath, out result))
- {
- return defaultAliases;
- }
- else
+ if (userProvidedAliases != null && userProvidedAliases.TryGetValue(propertyPath, out var result))
{
return result;
}
+
+ return defaultAliases;
}
- private string GetUserProvidedAlias(string propertyPath, string defaultAlias)
+ private static string GetUserProvidedAlias(IDictionary userProvidedAliases, string propertyPath, string defaultAlias)
{
- string[] columns;
- if (!userProvidedAliases.TryGetValue(propertyPath, out columns))
- {
- return defaultAlias;
- }
- else
+ if (userProvidedAliases != null && userProvidedAliases.TryGetValue(propertyPath, out var columns))
{
return columns[0];
}
+
+ return defaultAlias;
}
}
}
diff --git a/src/NHibernate/Loader/GeneratedCollectionAliases.cs b/src/NHibernate/Loader/GeneratedCollectionAliases.cs
index 71b127fb60e..932272ea19f 100644
--- a/src/NHibernate/Loader/GeneratedCollectionAliases.cs
+++ b/src/NHibernate/Loader/GeneratedCollectionAliases.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using NHibernate.Persister.Collection;
-using NHibernate.Util;
namespace NHibernate.Loader
{
@@ -16,38 +15,39 @@ public class GeneratedCollectionAliases : ICollectionAliases
private readonly string[] indexAliases;
private readonly string[] elementAliases;
private readonly string identifierAlias;
- private readonly IDictionary userProvidedAliases;
- public GeneratedCollectionAliases(IDictionary userProvidedAliases, ICollectionPersister persister,
- string suffix)
+ public GeneratedCollectionAliases(IDictionary userProvidedAliases, ICollectionPersister persister, string suffix)
{
this.suffix = suffix;
- this.userProvidedAliases = userProvidedAliases;
- keyAliases = GetUserProvidedAliases("key", persister.GetKeyColumnAliases(suffix));
-
- indexAliases = GetUserProvidedAliases("index", persister.GetIndexColumnAliases(suffix));
+ keyAliases = GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropKey, persister.GetKeyColumnAliases(suffix));
+ indexAliases = GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropIndex, persister.GetIndexColumnAliases(suffix));
// NH-1612: Add aliases for all composite element properties to support access
// to individual composite element properties in elements.
elementAliases = persister.ElementType.IsComponentType
- ? GetUserProvidedCompositeElementAliases(persister.GetElementColumnAliases(suffix))
- : GetUserProvidedAliases("element", persister.GetElementColumnAliases(suffix));
+ ? GetUserProvidedCompositeElementAliases(userProvidedAliases, persister.GetElementColumnAliases(suffix))
+ : GetUserProvidedAliases(userProvidedAliases, CollectionPersister.PropElement, persister.GetElementColumnAliases(suffix));
- identifierAlias = GetUserProvidedAlias("id", persister.GetIdentifierColumnAlias(suffix));
+ identifierAlias = GetUserProvidedAlias(userProvidedAliases, CollectionPersister.PropId, persister.GetIdentifierColumnAlias(suffix));
}
public GeneratedCollectionAliases(ICollectionPersister persister, string str)
- : this(CollectionHelper.EmptyDictionary(), persister, str) {}
+ : this(null, persister, str) {}
- private string[] GetUserProvidedCompositeElementAliases(string[] defaultAliases)
+ private static string[] GetUserProvidedCompositeElementAliases(IDictionary userProvidedAliases, string[] defaultAliases)
{
var aliases = new List();
- foreach (KeyValuePair userProvidedAlias in userProvidedAliases)
+ if (userProvidedAliases != null)
{
- if (userProvidedAlias.Key.StartsWith("element.", StringComparison.Ordinal))
+ foreach (var userProvidedAlias in userProvidedAliases)
{
- aliases.AddRange(userProvidedAlias.Value);
+ if (userProvidedAlias.Key.StartsWith(
+ CollectionPersister.PropElement + ".",
+ StringComparison.Ordinal))
+ {
+ aliases.AddRange(userProvidedAlias.Value);
+ }
}
}
@@ -103,40 +103,31 @@ public override string ToString()
base.ToString(), suffix, Join(keyAliases), Join(indexAliases), Join(elementAliases), identifierAlias);
}
- private static string Join(IEnumerable aliases)
+ private static string Join(string[] aliases)
{
- if (aliases == null)
- {
- return null;
- }
-
- return string.Join(", ", aliases);
+ return aliases == null
+ ? null
+ : string.Join(", ", aliases);
}
- private string[] GetUserProvidedAliases(string propertyPath, string[] defaultAliases)
+ private static string[] GetUserProvidedAliases(IDictionary userProvidedAliases, string propertyPath, string[] defaultAliases)
{
- string[] result;
- if (!userProvidedAliases.TryGetValue(propertyPath, out result))
- {
- return defaultAliases;
- }
- else
+ if (userProvidedAliases != null && userProvidedAliases.TryGetValue(propertyPath, out var result))
{
return result;
}
+
+ return defaultAliases;
}
- private string GetUserProvidedAlias(string propertyPath, string defaultAlias)
+ private static string GetUserProvidedAlias(IDictionary userProvidedAliases, string propertyPath, string defaultAlias)
{
- string[] columns;
- if (!userProvidedAliases.TryGetValue(propertyPath, out columns))
- {
- return defaultAlias;
- }
- else
+ if (userProvidedAliases != null && userProvidedAliases.TryGetValue(propertyPath, out var columns))
{
return columns[0];
}
+
+ return defaultAlias;
}
}
}
diff --git a/src/NHibernate/Loader/Hql/QueryLoader.cs b/src/NHibernate/Loader/Hql/QueryLoader.cs
index 9bb71eb2d3b..387b6d8fd17 100644
--- a/src/NHibernate/Loader/Hql/QueryLoader.cs
+++ b/src/NHibernate/Loader/Hql/QueryLoader.cs
@@ -46,6 +46,7 @@ public partial class QueryLoader : BasicLoader
private LockMode[] _defaultLockModes;
private IType[] _cacheTypes;
private ISet _uncacheableCollectionPersisters;
+ private Dictionary[] _collectionUserProvidedAliases;
public QueryLoader(QueryTranslatorImpl queryTranslator, ISessionFactoryImplementor factory, SelectClause selectClause)
: base(factory)
@@ -205,6 +206,11 @@ protected override ICollectionPersister[] CollectionPersisters
public override IType[] CacheTypes => _cacheTypes;
+ protected override IDictionary GetCollectionUserProvidedAlias(int index)
+ {
+ return _collectionUserProvidedAliases?[index];
+ }
+
private void Initialize(SelectClause selectClause)
{
IList fromElementList = selectClause.FromElementsForLoad;
@@ -225,6 +231,8 @@ private void Initialize(SelectClause selectClause)
_collectionOwners = new int[length];
_collectionSuffixes = new string[length];
CollectionFetches = new bool[length];
+ if (collectionFromElements.Any(qc => qc.QueryableCollection.IsManyToMany))
+ _collectionUserProvidedAliases = new Dictionary[length];
for (int i = 0; i < length; i++)
{
@@ -282,6 +290,24 @@ private void Initialize(SelectClause selectClause)
_selectLength++;
}
+ if (collectionFromElements != null && element.IsFetch && element.QueryableCollection?.IsManyToMany == true
+ && element.QueryableCollection.IsManyToManyFiltered(_queryTranslator.EnabledFilters))
+ {
+ var collectionIndex = collectionFromElements.IndexOf(element);
+
+ if (collectionIndex >= 0)
+ {
+ // When many-to-many is filtered we need to populate collection from element persister and not from bridge table.
+ // As bridge table will contain not-null values for filtered elements
+ // So do alias substitution for collection persister with element persister
+ // See test TestFilteredLinqQuery for details
+ _collectionUserProvidedAliases[collectionIndex] = new Dictionary
+ {
+ {CollectionPersister.PropElement, _entityPersisters[i].GetIdentifierAliases(Suffixes[i])}
+ };
+ }
+ }
+
_owners[i] = -1; //by default
if (element.IsFetch)
{
diff --git a/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs b/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs
index e03ad0fb9a0..0e7dc605d3b 100644
--- a/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs
+++ b/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs
@@ -27,6 +27,15 @@
namespace NHibernate.Persister.Collection
{
+ internal static class CollectionPersister
+ {
+ /// The property name of the "special" identifier property
+ public const string PropId = "id";
+ public const string PropElement = "element";
+ public const string PropKey = "key";
+ public const string PropIndex = "index";
+ }
+
///
/// Summary description for AbstractCollectionPersister.
///
@@ -1380,6 +1389,11 @@ public string GetManyToManyFilterFragment(string alias, IDictionary enabledFilters)
+ {
+ return IsManyToMany && (manyToManyWhereString != null || manyToManyFilterHelper.IsAffectedBy(enabledFilters));
+ }
public string[] ToColumns(string alias, string propertyName)
{
@@ -1512,17 +1526,17 @@ public string[] GetCollectionPropertyColumnAliases(string propertyName, string s
public void InitCollectionPropertyMap()
{
- InitCollectionPropertyMap("key", keyType, keyColumnAliases, keyColumnNames);
- InitCollectionPropertyMap("element", elementType, elementColumnAliases, elementColumnNames);
+ InitCollectionPropertyMap(CollectionPersister.PropKey, keyType, keyColumnAliases, keyColumnNames);
+ InitCollectionPropertyMap(CollectionPersister.PropElement, elementType, elementColumnAliases, elementColumnNames);
if (hasIndex)
{
- InitCollectionPropertyMap("index", indexType, indexColumnAliases, indexColumnNames);
+ InitCollectionPropertyMap(CollectionPersister.PropIndex, indexType, indexColumnAliases, indexColumnNames);
}
if (hasIdentifier)
{
- InitCollectionPropertyMap("id", identifierType, new string[] {identifierColumnAlias},
+ InitCollectionPropertyMap(CollectionPersister.PropId, identifierType, new string[] {identifierColumnAlias},
new string[] {identifierColumnName});
}
}
diff --git a/src/NHibernate/Persister/Collection/ICollectionPersister.cs b/src/NHibernate/Persister/Collection/ICollectionPersister.cs
index 4d87ea158b3..88d2401ae2d 100644
--- a/src/NHibernate/Persister/Collection/ICollectionPersister.cs
+++ b/src/NHibernate/Persister/Collection/ICollectionPersister.cs
@@ -285,6 +285,7 @@ public partial interface ICollectionPersister
object NotFoundObject { get; }
}
+ //6.0 TODO: Merge into ICollectionPersister
public static class CollectionPersisterExtensions
{
///
@@ -304,5 +305,18 @@ public static int GetBatchSize(this ICollectionPersister persister)
return 1;
}
+
+ ///
+ /// Is this persister has enabled many-to-many filter or has many-to-many where clause
+ ///
+ internal static bool IsManyToManyFiltered(this ICollectionPersister persister, IDictionary enabledFilters)
+ {
+ if (persister is AbstractCollectionPersister acp)
+ {
+ return acp.IsManyToManyFiltered(enabledFilters);
+ }
+
+ return persister.IsManyToMany && !string.IsNullOrEmpty(persister.GetManyToManyFilterFragment("x", enabledFilters));
+ }
}
}