diff --git a/Orm/Xtensive.Orm.Tests/Storage/SessionEventsTest.cs b/Orm/Xtensive.Orm.Tests/Storage/SessionEventsTest.cs index c8b5bebcf7..f097efac41 100644 --- a/Orm/Xtensive.Orm.Tests/Storage/SessionEventsTest.cs +++ b/Orm/Xtensive.Orm.Tests/Storage/SessionEventsTest.cs @@ -1,6 +1,6 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2009-2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Alex Kofman // Created: 2009.10.08 @@ -45,6 +45,9 @@ protected override DomainConfiguration BuildConfiguration() private EventArgs persistingArgs; private EventArgs persistedArgs; + private EventArgs changesCancelingArgs; + private EventArgs changesCanceledArgs; + private EntityEventArgs entityCreatedArgs; private EntityEventArgs entityRemoving; private EntityEventArgs entityRemoved; @@ -100,6 +103,9 @@ public void MainTest() session.Events.Persisting += (sender, e) => persistingArgs = e; session.Events.Persisted += (sender, e) => persistedArgs = e; + session.Events.ChangesCanceling += (sender, e) => changesCancelingArgs = e; + session.Events.ChangesCanceled += (sender, e) => changesCanceledArgs = e; + session.Events.EntityCreated += (sender, e) => entityCreatedArgs = e; session.Events.EntityRemoving += (sender, e) => entityRemoving = e; session.Events.EntityRemove += (sender, e) => entityRemoved = e; @@ -113,6 +119,7 @@ public void MainTest() RollbackTransaction(); ErrorOnCommit(); EditEntity(); + CancelChanges(); } } @@ -221,5 +228,26 @@ private void EditEntity() Assert.AreEqual(entity, entityRemoved.Entity); } } + + private void CancelChanges() + { + var session = Session.Demand(); + using (var transactionScope = session.OpenTransaction()) { + ClearEvents(); + + var megaEntity = new MegaEntity { Value = 1 }; + + session.CancelChanges(); + } + + Assert.IsNotNull(transactionRollbackingArgs); + Assert.IsNotNull(transactionRollbackedArgs); + Assert.IsNotNull(changesCancelingArgs); + Assert.IsNotNull(changesCanceledArgs); + Assert.IsNull(persistingArgs); + Assert.IsNull(persistedArgs); + Assert.IsNull(transactionCommitingArgs); + Assert.IsNull(transactionCommitedArgs); + } } } \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Orm/Session.Persist.cs b/Orm/Xtensive.Orm/Orm/Session.Persist.cs index c5e409d58c..a4b126345d 100644 --- a/Orm/Xtensive.Orm/Orm/Session.Persist.cs +++ b/Orm/Xtensive.Orm/Orm/Session.Persist.cs @@ -1,6 +1,6 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2007-2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Dmitri Maximov // Created: 2007.08.10 @@ -57,9 +57,15 @@ public void SaveChanges() /// Unable to cancel changes for non-disconnected session. Use transaction boundaries to control the state. public void CancelChanges() { + SystemEvents.NotifyChangesCanceling(); + Events.NotifyChangesCanceling(); + CancelEntitySetsChanges(); CancelEntitiesChanges(); NonPairedReferencesRegistry.Clear(); + + SystemEvents.NotifyChangesCanceled(); + Events.NotifyChangesCanceled(); } internal void Persist(PersistReason reason) diff --git a/Orm/Xtensive.Orm/Orm/SessionEventAccessor.cs b/Orm/Xtensive.Orm/Orm/SessionEventAccessor.cs index a1a798a3ae..ae26b4f4d6 100644 --- a/Orm/Xtensive.Orm/Orm/SessionEventAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/SessionEventAccessor.cs @@ -1,6 +1,6 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2010-2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Alex Yakunin // Created: 2010.08.10 @@ -67,6 +67,16 @@ public sealed class SessionEventAccessor /// public event EventHandler Persisted; + /// + /// Occurs when is about to changes. + /// + public event EventHandler ChangesCanceling; + + /// + /// Occurs when changes are canceled. + /// + public event EventHandler ChangesCanceled; + /// /// Occurs when local created. /// @@ -284,6 +294,18 @@ internal void NotifyPersisted() Persisted(this, EventArgs.Empty); } + internal void NotifyChangesCanceling() + { + if (ChangesCanceling != null && AreNotificationsEnabled()) + ChangesCanceling(this, EventArgs.Empty); + } + + internal void NotifyChangesCanceled() + { + if (ChangesCanceled != null && AreNotificationsEnabled()) + ChangesCanceled(this, EventArgs.Empty); + } + internal void NotifyKeyGenerated(Key key) { if (KeyGenerated!=null && AreNotificationsEnabled())