嗯,这是我的情况:
我们有不希望删除数据的表。有一个名为isDeleted的列应该更新而不是删除它。
我想用EF5开发随附的网络应用程序,但我有一个问题。我该如何实施这一限制?
我可以使用存储过程来删除和选择但我希望有一种方法来使用EF中的标准函数,只是改变它们的工作方式。哪种方式不那么艰难,我有什么选择可以达到我想要的,因为我猜我不是第一个要求这个的人?
答案 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)
你可以这样做:
您可以在此答案中找到工作代码: 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;