diff --git a/src/NHibernate/Action/BulkOperationCleanupAction.cs b/src/NHibernate/Action/BulkOperationCleanupAction.cs index edd5b8f20bd..f3f2d69f023 100644 --- a/src/NHibernate/Action/BulkOperationCleanupAction.cs +++ b/src/NHibernate/Action/BulkOperationCleanupAction.cs @@ -14,34 +14,49 @@ namespace NHibernate.Action /// Implementation of BulkOperationCleanupAction. /// [Serializable] - public partial class BulkOperationCleanupAction : IAsyncExecutable, IAfterTransactionCompletionProcess + public partial class BulkOperationCleanupAction : + IAsyncExecutable, + IAfterTransactionCompletionProcess, + ICacheableExecutable { - private readonly ISessionImplementor session; - private readonly HashSet affectedEntityNames = new HashSet(); - private readonly HashSet affectedCollectionRoles = new HashSet(); - private readonly List spaces; + private readonly ISessionFactoryImplementor _factory; + private readonly HashSet affectedEntityNames; + private readonly HashSet affectedCollectionRoles; + private readonly string[] spaces; + private readonly bool _hasCache; public BulkOperationCleanupAction(ISessionImplementor session, IQueryable[] affectedQueryables) { - this.session = session; - List tmpSpaces = new List(); - for (int i = 0; i < affectedQueryables.Length; i++) + _factory = session.Factory; + var tmpSpaces = new HashSet(); + foreach (var queryables in affectedQueryables) { - if (affectedQueryables[i].HasCache) + if (queryables.HasCache) { - affectedEntityNames.Add(affectedQueryables[i].EntityName); + _hasCache = true; + if (affectedEntityNames == null) + { + affectedEntityNames = new HashSet(); + } + + affectedEntityNames.Add(queryables.EntityName); } - ISet roles = session.Factory.GetCollectionRolesByEntityParticipant(affectedQueryables[i].EntityName); + + var roles = _factory.GetCollectionRolesByEntityParticipant(queryables.EntityName); if (roles != null) { + if (affectedCollectionRoles == null) + { + affectedCollectionRoles = new HashSet(); + } + affectedCollectionRoles.UnionWith(roles); } - for (int y = 0; y < affectedQueryables[i].QuerySpaces.Length; y++) - { - tmpSpaces.Add(affectedQueryables[i].QuerySpaces[y]); - } + + tmpSpaces.UnionWith(queryables.QuerySpaces); } - spaces = new List(tmpSpaces); + + spaces = tmpSpaces.ToArray(); } /// @@ -50,35 +65,44 @@ public BulkOperationCleanupAction(ISessionImplementor session, IQueryable[] affe public BulkOperationCleanupAction(ISessionImplementor session, ISet querySpaces) { //from H3.2 TODO: cache the autodetected information and pass it in instead. - this.session = session; + _factory = session.Factory; - ISet tmpSpaces = new HashSet(querySpaces); - ISessionFactoryImplementor factory = session.Factory; - IDictionary acmd = factory.GetAllClassMetadata(); + var tmpSpaces = new HashSet(querySpaces); + var acmd = _factory.GetAllClassMetadata(); foreach (KeyValuePair entry in acmd) { - string entityName = entry.Key; - IEntityPersister persister = factory.GetEntityPersister(entityName); - string[] entitySpaces = persister.QuerySpaces; + var entityName = entry.Key; + var persister = _factory.GetEntityPersister(entityName); + var entitySpaces = persister.QuerySpaces; if (AffectedEntity(querySpaces, entitySpaces)) { if (persister.HasCache) { + _hasCache = true; + if (affectedEntityNames == null) + { + affectedEntityNames = new HashSet(); + } + affectedEntityNames.Add(persister.EntityName); } - ISet roles = session.Factory.GetCollectionRolesByEntityParticipant(persister.EntityName); + + var roles = session.Factory.GetCollectionRolesByEntityParticipant(persister.EntityName); if (roles != null) { + if (affectedCollectionRoles == null) + { + affectedCollectionRoles = new HashSet(); + } + affectedCollectionRoles.UnionWith(roles); } - for (int y = 0; y < entitySpaces.Length; y++) - { - tmpSpaces.Add(entitySpaces[y]); - } + + tmpSpaces.UnionWith(entitySpaces); } } - spaces = new List(tmpSpaces); + spaces = tmpSpaces.ToArray(); } private bool AffectedEntity(ISet querySpaces, string[] entitySpaces) @@ -91,12 +115,11 @@ private bool AffectedEntity(ISet querySpaces, string[] entitySpaces) return entitySpaces.Any(querySpaces.Contains); } + public bool HasCache => _hasCache; + #region IExecutable Members - public string[] PropertySpaces - { - get { return spaces.ToArray(); } - } + public string[] PropertySpaces => spaces; public void BeforeExecutions() { @@ -132,17 +155,17 @@ public void ExecuteAfterTransactionCompletion(bool success) private void EvictCollectionRegions() { - if (affectedCollectionRoles != null && affectedCollectionRoles.Any()) + if (affectedCollectionRoles != null) { - session.Factory.EvictCollection(affectedCollectionRoles); + _factory.EvictCollection(affectedCollectionRoles); } } private void EvictEntityRegions() { - if (affectedEntityNames != null && affectedEntityNames.Any()) + if (affectedEntityNames != null) { - session.Factory.EvictEntity(affectedEntityNames); + _factory.EvictEntity(affectedEntityNames); } } diff --git a/src/NHibernate/Action/CollectionAction.cs b/src/NHibernate/Action/CollectionAction.cs index ca5be713bf6..ccd94d86bee 100644 --- a/src/NHibernate/Action/CollectionAction.cs +++ b/src/NHibernate/Action/CollectionAction.cs @@ -14,7 +14,12 @@ namespace NHibernate.Action /// Any action relating to insert/update/delete of a collection /// [Serializable] - public abstract partial class CollectionAction : IAsyncExecutable, IComparable, IDeserializationCallback, IAfterTransactionCompletionProcess + public abstract partial class CollectionAction: + IAsyncExecutable, + IComparable, + IDeserializationCallback, + IAfterTransactionCompletionProcess, + ICacheableExecutable { private readonly object key; [NonSerialized] private ICollectionPersister persister; @@ -77,6 +82,8 @@ protected internal ISessionImplementor Session get { return session; } } + public bool HasCache => persister.HasCache; + #region IExecutable Members /// diff --git a/src/NHibernate/Action/EntityAction.cs b/src/NHibernate/Action/EntityAction.cs index 70b2b1e60c2..0407684b385 100644 --- a/src/NHibernate/Action/EntityAction.cs +++ b/src/NHibernate/Action/EntityAction.cs @@ -18,7 +18,8 @@ public abstract partial class EntityAction : IBeforeTransactionCompletionProcess, IAfterTransactionCompletionProcess, IComparable, - IDeserializationCallback + IDeserializationCallback, + ICacheableExecutable { private readonly string entityName; private readonly object id; @@ -195,5 +196,7 @@ public void ExecuteAfterTransactionCompletion(bool success) { AfterTransactionCompletionProcessImpl(success); } + + public bool HasCache => persister.HasCache; } } diff --git a/src/NHibernate/Action/ICacheableExecutable.cs b/src/NHibernate/Action/ICacheableExecutable.cs new file mode 100644 index 00000000000..514cf4177b2 --- /dev/null +++ b/src/NHibernate/Action/ICacheableExecutable.cs @@ -0,0 +1,8 @@ +namespace NHibernate.Action +{ + //6.0 TODO: Merge to IExecutable + public interface ICacheableExecutable : IExecutable + { + bool HasCache { get; } + } +} \ No newline at end of file diff --git a/src/NHibernate/Async/Action/BulkOperationCleanupAction.cs b/src/NHibernate/Async/Action/BulkOperationCleanupAction.cs index 18d4553f24f..1ee17a5ef9d 100644 --- a/src/NHibernate/Async/Action/BulkOperationCleanupAction.cs +++ b/src/NHibernate/Async/Action/BulkOperationCleanupAction.cs @@ -20,7 +20,10 @@ namespace NHibernate.Action { - public partial class BulkOperationCleanupAction : IAsyncExecutable, IAfterTransactionCompletionProcess + public partial class BulkOperationCleanupAction : + IAsyncExecutable, + IAfterTransactionCompletionProcess, + ICacheableExecutable { #region IExecutable Members @@ -72,18 +75,11 @@ private Task EvictCollectionRegionsAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - if (affectedCollectionRoles != null && affectedCollectionRoles.Any()) - { - return session.Factory.EvictCollectionAsync(affectedCollectionRoles, cancellationToken); - } - return Task.CompletedTask; - } - catch (Exception ex) + if (affectedCollectionRoles != null) { - return Task.FromException(ex); + return _factory.EvictCollectionAsync(affectedCollectionRoles, cancellationToken); } + return Task.CompletedTask; } private Task EvictEntityRegionsAsync(CancellationToken cancellationToken) @@ -92,18 +88,11 @@ private Task EvictEntityRegionsAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - try - { - if (affectedEntityNames != null && affectedEntityNames.Any()) - { - return session.Factory.EvictEntityAsync(affectedEntityNames, cancellationToken); - } - return Task.CompletedTask; - } - catch (Exception ex) + if (affectedEntityNames != null) { - return Task.FromException(ex); + return _factory.EvictEntityAsync(affectedEntityNames, cancellationToken); } + return Task.CompletedTask; } #endregion diff --git a/src/NHibernate/Async/Action/CollectionAction.cs b/src/NHibernate/Async/Action/CollectionAction.cs index 16a2a27460e..bf64f7f9453 100644 --- a/src/NHibernate/Async/Action/CollectionAction.cs +++ b/src/NHibernate/Async/Action/CollectionAction.cs @@ -22,7 +22,12 @@ namespace NHibernate.Action { using System.Threading.Tasks; using System.Threading; - public abstract partial class CollectionAction : IAsyncExecutable, IComparable, IDeserializationCallback, IAfterTransactionCompletionProcess + public abstract partial class CollectionAction: + IAsyncExecutable, + IComparable, + IDeserializationCallback, + IAfterTransactionCompletionProcess, + ICacheableExecutable { protected async Task GetKeyAsync(CancellationToken cancellationToken) diff --git a/src/NHibernate/Async/Action/EntityAction.cs b/src/NHibernate/Async/Action/EntityAction.cs index a61ececcf29..778cc54d859 100644 --- a/src/NHibernate/Async/Action/EntityAction.cs +++ b/src/NHibernate/Async/Action/EntityAction.cs @@ -25,7 +25,8 @@ public abstract partial class EntityAction : IBeforeTransactionCompletionProcess, IAfterTransactionCompletionProcess, IComparable, - IDeserializationCallback + IDeserializationCallback, + ICacheableExecutable { #region IExecutable Members diff --git a/src/NHibernate/Async/Engine/ActionQueue.cs b/src/NHibernate/Async/Engine/ActionQueue.cs index 3a0ab25b1f5..f0207c5bd28 100644 --- a/src/NHibernate/Async/Engine/ActionQueue.cs +++ b/src/NHibernate/Async/Engine/ActionQueue.cs @@ -45,7 +45,7 @@ private Task PreInvalidateCachesAsync(CancellationToken cancellationToken) { return Task.FromCanceled(cancellationToken); } - if (session.Factory.Settings.IsQueryCacheEnabled && executedSpaces.Count > 0) + if (executedSpaces?.Count > 0) { return session.Factory.UpdateTimestampsCache.PreInvalidateAsync(executedSpaces, cancellationToken); } @@ -165,12 +165,11 @@ public async Task AfterTransactionCompletionAsync(bool success, CancellationToke private async Task InvalidateCachesAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - if (session.Factory.Settings.IsQueryCacheEnabled && executedSpaces.Count > 0) + if (executedSpaces?.Count > 0) { await (session.Factory.UpdateTimestampsCache.InvalidateAsync(executedSpaces, cancellationToken)).ConfigureAwait(false); + executedSpaces.Clear(); } - - executedSpaces.Clear(); } private partial class BeforeTransactionCompletionProcessQueue { diff --git a/src/NHibernate/Engine/ActionQueue.cs b/src/NHibernate/Engine/ActionQueue.cs index 36a76591edd..0f28cbf5284 100644 --- a/src/NHibernate/Engine/ActionQueue.cs +++ b/src/NHibernate/Engine/ActionQueue.cs @@ -59,7 +59,7 @@ public ActionQueue(ISessionImplementor session) afterTransactionProcesses = new AfterTransactionCompletionProcessQueue(); beforeTransactionProcesses = new BeforeTransactionCompletionProcessQueue(); - executedSpaces = new HashSet(); + executedSpaces = session.Factory.Settings.IsQueryCacheEnabled ? new HashSet() : null; } public virtual void Clear() @@ -172,7 +172,7 @@ private void ExecuteActions(List list) where T: IExecutable private void PreInvalidateCaches() { - if (session.Factory.Settings.IsQueryCacheEnabled && executedSpaces.Count > 0) + if (executedSpaces?.Count > 0) { session.Factory.UpdateTimestampsCache.PreInvalidate(executedSpaces); } @@ -216,7 +216,10 @@ private void RegisterCleanupActions(IExecutable executable) RegisterProcess(executable.AfterTransactionCompletionProcess); #pragma warning restore 618,619 } - if (executable.PropertySpaces != null) + + if (executedSpaces != null && + executable.PropertySpaces != null && + (!(executable is ICacheableExecutable ce) || ce.HasCache)) { executedSpaces.UnionWith(executable.PropertySpaces); } @@ -294,12 +297,11 @@ public void AfterTransactionCompletion(bool success) private void InvalidateCaches() { - if (session.Factory.Settings.IsQueryCacheEnabled && executedSpaces.Count > 0) + if (executedSpaces?.Count > 0) { session.Factory.UpdateTimestampsCache.Invalidate(executedSpaces); + executedSpaces.Clear(); } - - executedSpaces.Clear(); } ///