EF5:如何更改默认的删除功能来实现我自己的

时间:2013-09-24 15:05:46

标签: .net entity-framework

嗯,这是我的情况:

我们有不希望删除数据的表。有一个名为isDeleted的列应该更新而不是删除它。

我想用EF5开发随附的网络应用程序,但我有一个问题。我该如何实施这一限制?

我可以使用存储过程来删除和选择但我希望有一种方法来使用EF中的标准函数,只是改变它们的工作方式。哪种方式不那么艰难,我有什么选择可以达到我想要的,因为我猜我不是第一个要求这个的人?

3 个答案:

答案 0 :(得分:4)

您可以覆盖DbContext的SaveChanges方法。例如。你想禁止删除产品。您可以将IsDeleted标志设置为true的实体保存,而不是删除它们:

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

另一个选项 - 如果有人试图删除产品,则引发异常:

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

你也可以简单地将实体状态设置为不变,但我认为它不是很好的解决方案。

答案 1 :(得分:1)

你可以这样做:

  1. 在OnModelCreating中为每个可以软删除的实体添加一个IsDeleted鉴别器
  2. 覆盖SaveChanges并查找要删除的所有条目
  3. 在这些条目上运行SQL以设置IsDeleted鉴别器,然后将其状态设置为“已分离”
  4. 更改任何唯一索引以忽略任何软删除记录
  5. 您可以在此答案中找到工作代码: How to soft delete using Entity Framework Code First

    您也可以使用存储过程而不是步骤2和3中使用的代码 - 我一直在研究如何EF6 generates the stored procedures for you。您添加如下所示的代码:

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

    导致迁移包括:

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

    现在,这是一个在从删除到更新的迁移中更改sql的情况。用text / replace来做这件事并不太费劲,但如果我们可以更改用于生成CreateStoredProcedure调用的模板,那会不会很酷?....

答案 2 :(得分:0)

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;