NickStrupat / EntityFramework.Triggers

Adds events for entity inserting, inserted, updating, updated, deleting, and deleted
MIT License
373 stars 46 forks source link

Soft deletes do not trigger Update events #47

Closed iwes closed 3 years ago

iwes commented 5 years ago

When IDeletingEntry.Cancel is set true, it seems logical that the Updating/Updated events should then fire for that entry.

Is this the expected behavior?

Sample:

static bool SoftDeleteEnabled = false;

void Main()
{
    TestContext.Migrate();

    var db = new TestContext();
    var widget = db.Widgets.Create();
    db.Widgets.Add(widget);

    widget.Value = DateTime.Now.ToString();
    db.SaveChanges(); // Inserting, Inserted

    widget.Value = DateTime.Today.ToString();
    db.SaveChanges(); // Updating, Updated

    db.Widgets.Remove(widget);
    db.SaveChanges(); // Deleting, Deleted

    db.Widgets.Add(widget);
    db.SaveChanges(); // Inserting, Inserted

    SoftDeleteEnabled = true;
    db.Widgets.Remove(widget);
    db.SaveChanges(); // Deleting

}

public class Widget
{
    public int Id { get; set; }
    public string Value { get; set; }
    public DateTime? Deleted { get; set; }

    static Widget()
    {
        Triggers<Widget>.Inserting += entry => Console.WriteLine("Inserting");
        Triggers<Widget>.InsertFailed += entry => Console.WriteLine("InsertFailed");
        Triggers<Widget>.Inserted += entry => Console.WriteLine("Inserted");

        Triggers<Widget>.Updating += entry => Console.WriteLine("Updating");
        Triggers<Widget>.UpdateFailed += entry => Console.WriteLine("UpdateFailed");
        Triggers<Widget>.Updated += entry => Console.WriteLine("Updated");

        Triggers<Widget>.Deleting += entry => Console.WriteLine("Deleting");
        Triggers<Widget>.DeleteFailed += entry => Console.WriteLine("DeleteFailed");
        Triggers<Widget>.Deleted += entry => Console.WriteLine("Deleted");

        Triggers<Widget>.Deleting += entry =>
        {
            if (SoftDeleteEnabled)
            {
                entry.Cancel = true;
                entry.Entity.Deleted = DateTime.Now;
            }
        };
    }
}

public class TestContext : DbContextWithTriggers
{
    public TestContext()
    {
        Database.Log = Util.SqlOutputWriter.Write;
    }

    public DbSet<Widget> Widgets { get; set; }

    public static void Migrate()
    {
        using (var db = new TestContext())
        {
            var m = new DropCreateDatabaseIfModelChanges<TestContext>();
            m.InitializeDatabase(db);
        }
    }
}
NickStrupat commented 5 years ago

@iwes The designed behavior where entry.Cancel == true is that the changes you make to the entity within the Deleting handler will be persisted to the database, but the update handlers won't run since the original operation was a deletion.

Gilmar-Gomes commented 4 years ago

OK! So how do I simulate this situation? In my project, I need to notify CRUD operations for audit. THX!