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())