Skip to content

Commit cb1930e

Browse files
NH-2319 - Refactoring to be squashed.
1 parent d295d09 commit cb1930e

File tree

3 files changed

+42
-97
lines changed

3 files changed

+42
-97
lines changed

src/NHibernate/Impl/SessionImpl.cs

Lines changed: 32 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -550,48 +550,31 @@ public override IQuery CreateQuery(IQueryExpression queryExpression)
550550

551551
public override void List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
552552
{
553-
using (new SessionIdLoggingContext(SessionId))
554-
{
555-
CheckAndUpdateSessionStatus();
556-
queryParameters.ValidateParameters();
557-
var plan = GetHQLQueryPlan(queryExpression, false);
558-
559-
AutoFlushIfRequired(plan.QuerySpaces);
560-
561-
bool success = false;
562-
using (SuspendAutoFlush()) //stops flush being called multiple times if this method is recursively called
563-
{
564-
try
565-
{
566-
plan.PerformList(queryParameters, this, results);
567-
success = true;
568-
}
569-
catch (HibernateException)
570-
{
571-
// Do not call Convert on HibernateExceptions
572-
throw;
573-
}
574-
catch (Exception e)
575-
{
576-
throw Convert(e, "Could not execute query");
577-
}
578-
finally
579-
{
580-
AfterOperation(success);
581-
}
582-
}
583-
}
553+
List(queryExpression, queryParameters, results, null);
584554
}
585555

586556
protected override void ListFilter(object collection, IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
557+
{
558+
if (collection == null)
559+
throw new ArgumentNullException(nameof(collection));
560+
List(queryExpression, queryParameters, results, collection);
561+
}
562+
563+
private void List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, object filterConnection)
587564
{
588565
using (new SessionIdLoggingContext(SessionId))
589566
{
590567
CheckAndUpdateSessionStatus();
591568
queryParameters.ValidateParameters();
592-
var plan = GetFilterQueryPlan(collection, queryExpression, queryParameters, false);
593569

594-
AutoFlushIfRequired(plan.QuerySpaces);
570+
var isFilter = filterConnection != null;
571+
var plan = isFilter
572+
? GetFilterQueryPlan(filterConnection, queryExpression, queryParameters, false)
573+
: GetHQLQueryPlan(queryExpression, false);
574+
575+
// GetFilterQueryPlan has already auto flushed or fully flush.
576+
if (!isFilter)
577+
AutoFlushIfRequired(plan.QuerySpaces);
595578

596579
bool success = false;
597580
using (SuspendAutoFlush()) //stops flush being called multiple times if this method is recursively called
@@ -751,69 +734,27 @@ public override IQuery CreateFilter(object collection, IQueryExpression queryExp
751734

752735
private IQueryExpressionPlan GetFilterQueryPlan(object collection, IQueryExpression queryExpression, QueryParameters parameters, bool shallow)
753736
{
754-
using (new SessionIdLoggingContext(SessionId))
755-
{
756-
CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection);
757-
ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister;
758-
759-
IQueryExpressionPlan plan;
760-
if (roleBeforeFlush == null)
761-
{
762-
// if it was previously unreferenced, we need to flush in order to
763-
// get its state into the database in order to execute query
764-
Flush();
765-
entry = persistenceContext.GetCollectionEntryOrNull(collection);
766-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
767-
if (roleAfterFlush == null)
768-
{
769-
throw new QueryException("The collection was unreferenced");
770-
}
771-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleAfterFlush.Role, shallow, EnabledFilters);
772-
}
773-
else
774-
{
775-
// otherwise, we only need to flush if there are in-memory changes
776-
// to the queried tables
777-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleBeforeFlush.Role, shallow, EnabledFilters);
778-
779-
if (AutoFlushIfRequired(plan.QuerySpaces))
780-
{
781-
// might need to run a different filter entirely after the flush
782-
// because the collection role may have changed
783-
entry = persistenceContext.GetCollectionEntryOrNull(collection);
784-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
785-
if (roleBeforeFlush != roleAfterFlush)
786-
{
787-
if (roleAfterFlush == null)
788-
{
789-
throw new QueryException("The collection was dereferenced");
790-
}
791-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, roleAfterFlush.Role, shallow, EnabledFilters);
792-
}
793-
}
794-
}
795-
796-
if (parameters != null)
797-
{
798-
parameters.PositionalParameterValues[0] = entry.LoadedKey;
799-
parameters.PositionalParameterTypes[0] = entry.LoadedPersister.KeyType;
800-
}
801-
802-
return plan;
803-
}
737+
return GetFilterQueryPlan(collection, parameters,
738+
role => Factory.QueryPlanCache.GetFilterQueryPlan(queryExpression, role, shallow, EnabledFilters));
804739
}
805740

806741
private IQueryExpressionPlan GetFilterQueryPlan(object collection, string filter, QueryParameters parameters, bool shallow)
742+
{
743+
return GetFilterQueryPlan(collection, parameters,
744+
role => Factory.QueryPlanCache.GetFilterQueryPlan(filter, role, shallow, EnabledFilters));
745+
}
746+
747+
private IQueryExpressionPlan GetFilterQueryPlan(object collection, QueryParameters parameters, Func<string, IQueryExpressionPlan> getPlanForRole)
807748
{
808749
using (new SessionIdLoggingContext(SessionId))
809750
{
810751
if (collection == null)
811752
{
812-
throw new ArgumentNullException("collection", "null collection passed to filter");
753+
throw new ArgumentNullException(nameof(collection), "null collection passed to filter");
813754
}
814755

815-
CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection);
816-
ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister;
756+
var entry = persistenceContext.GetCollectionEntryOrNull(collection);
757+
var roleBeforeFlush = entry?.LoadedPersister;
817758

818759
IQueryExpressionPlan plan;
819760
if (roleBeforeFlush == null)
@@ -822,31 +763,31 @@ private IQueryExpressionPlan GetFilterQueryPlan(object collection, string filter
822763
// get its state into the database in order to execute query
823764
Flush();
824765
entry = persistenceContext.GetCollectionEntryOrNull(collection);
825-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
766+
var roleAfterFlush = entry?.LoadedPersister;
826767
if (roleAfterFlush == null)
827768
{
828769
throw new QueryException("The collection was unreferenced");
829770
}
830-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters);
771+
plan = getPlanForRole(roleAfterFlush.Role);
831772
}
832773
else
833774
{
834775
// otherwise, we only need to flush if there are in-memory changes
835776
// to the queried tables
836-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleBeforeFlush.Role, shallow, EnabledFilters);
777+
plan = getPlanForRole(roleBeforeFlush.Role);
837778
if (AutoFlushIfRequired(plan.QuerySpaces))
838779
{
839780
// might need to run a different filter entirely after the flush
840781
// because the collection role may have changed
841782
entry = persistenceContext.GetCollectionEntryOrNull(collection);
842-
ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister;
783+
var roleAfterFlush = entry?.LoadedPersister;
843784
if (roleBeforeFlush != roleAfterFlush)
844785
{
845786
if (roleAfterFlush == null)
846787
{
847788
throw new QueryException("The collection was dereferenced");
848789
}
849-
plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters);
790+
plan = getPlanForRole(roleAfterFlush.Role);
850791
}
851792
}
852793
}

src/NHibernate/Linq/NhQueryable.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public NhQueryable(ISessionImplementor session)
2727

2828
// This constructor is called by our users, create a new IQueryExecutor.
2929
public NhQueryable(ISessionImplementor session, string entityName)
30-
: base(QueryProviderFactory.CreateQueryProvider(session))
30+
: base(QueryProviderFactory.CreateQueryProvider(session, null))
3131
{
3232
EntityName = entityName;
3333
}
@@ -47,7 +47,7 @@ public NhQueryable(IQueryProvider provider, Expression expression, string entity
4747
}
4848

4949
public NhQueryable(ISessionImplementor session, object collection)
50-
: base(new DefaultQueryProvider(session, collection))
50+
: base(QueryProviderFactory.CreateQueryProvider(session, collection))
5151
{
5252
EntityName = typeof(T).FullName;
5353
}
@@ -59,4 +59,4 @@ public override string ToString()
5959
return "NHibernate.Linq.NhQueryable`1[" + EntityName + "]";
6060
}
6161
}
62-
}
62+
}

src/NHibernate/Linq/QueryProviderFactory.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@ static class QueryProviderFactory
99
/// Builds a new query provider.
1010
/// </summary>
1111
/// <param name="session">A session.</param>
12+
/// <param name="collection">If the query is to be filtered as belonging to an entity collection, the collection.</param>
1213
/// <returns>The new query provider instance.</returns>
13-
public static INhQueryProvider CreateQueryProvider(ISessionImplementor session)
14+
public static INhQueryProvider CreateQueryProvider(ISessionImplementor session, object collection)
1415
{
1516
if (session.Factory.Settings.LinqQueryProviderType == null)
1617
{
17-
return new DefaultQueryProvider(session);
18+
return new DefaultQueryProvider(session, collection);
1819
}
1920
else
2021
{
21-
return Activator.CreateInstance(session.Factory.Settings.LinqQueryProviderType, session) as INhQueryProvider;
22+
// For backward compatibility, prioritize using the version without collection.
23+
return (collection == null
24+
? Activator.CreateInstance(session.Factory.Settings.LinqQueryProviderType, session)
25+
: Activator.CreateInstance(session.Factory.Settings.LinqQueryProviderType, session, collection)) as INhQueryProvider;
2226
}
2327
}
2428
}

0 commit comments

Comments
 (0)