EF5: How to alter the default Delete function to implement my own

纵饮孤独 提交于 2020-01-13 11:34:08

问题


Well, here is my situation:

We have tables that we dont want ever to delete the data. There is a column which is called isDeleted that is supposed to be updated instead instead of deleting it.

I want to develop the accompanying web app with EF5 but i have a problem there. How do i implement that restriction?

I could use stored procedures to delete and select but i was hoping for a way to use the standard functions in EF, just changing how they work. Which way is less arduous and what options i have to achieve what i want, since i´m guessing i´m not the first person to ask for this?


回答1:


You can override SaveChanges method of your DbContext. E.g. you want to forbid deleting products. You can save entities with IsDeleted flag set to true instead of deleting them:

public override int SaveChanges()
{
    var deletedPersonEntries = ChangeTracker.Entries<Person>()
                                    .Where(e => e.State == EntityState.Deleted);

    foreach (var e in deletedPersonEntries)
    {
        e.State = EntityState.Unchanged;
        e.Entity.IsDeleted = true;
    }

    return base.SaveChanges();
}

Another option - raise exception if someone tries to delete product:

if (deltedProductEntries.Any())
    throw new Exception("You should not delete products!");

You also can simply set entities state to unchanged, but I don't think its very good solution.




回答2:


You can do it like this:

  1. In OnModelCreating add an IsDeleted discriminator to every entity that can be soft deleted
  2. Override SaveChanges and find all the entries to be deleted
  3. Run SQL on these entries to set the IsDeleted discriminator then set their state to "detached"
  4. Change any unique indexes to ignore any soft deleted records

You can find working code at this answer: How to soft delete using Entity Framework Code First

You could also use stored procedures instead of the code used in steps 2 and 3 - and I've been looking at how EF6 generates the stored procedures for you. You add code that looks like this:

modelBuilder.Entity<AdministrativeArea>().MapToStoredProcedures();

and that results in a migration that includes this:

        CreateStoredProcedure(
            "dbo.AdministrativeArea_Delete",
            p => new
                {
                    ID = p.Int(),
                },
            body:
                @"DELETE [dbo].[AdministrativeAreas]
                  WHERE ([ID] = @ID)"
        );

Now it's a case of altering the sql in the migration from a delete to an update. It wouldn't be too arduous to do it with text/replace but wouldn't it be cool if we could change the template used to generate the CreateStoredProcedure calls?....




回答3:


CREATE VIEW Foo
AS 
SELECT
    f.Id,
    f.Bar,
    f.Baz,
    f.Qux
FROM Foo_Table
Where f.Deleted = 0;

CREATE TRIGGER Foo_Delete
ON Foo
Instead of Delete
AS 
BEGIN
    Update
        Foo_Table f
    SET
        f.Deleted = 1
    WHERE
        f.Id IN (SELECT Id from Deleted)
END;


来源:https://stackoverflow.com/questions/18985295/ef5-how-to-alter-the-default-delete-function-to-implement-my-own

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!