我有一個工作解決方案Soft Delete in Entity Framework Code First可能有所幫助。
關鍵是,您可以爲您希望能夠軟刪除的每個模型添加一個鑑別器。在第一個代碼是這樣完成的:
modelBuilder.Entity<Foo>().Map(m => m.Requires("IsDeleted").HasValue(false));
這使得它無形的背景下,因此您可以使用SQL做刪除。
如果這是在數據庫中你的「條件映射」的同義的第一,然後修改SQL一個辦法就是從那裏覆蓋的SaveChanges和運行SQL:用於Get Table Name explained here
public override int SaveChanges()
{
foreach (var entry in ChangeTracker.Entries()
.Where(p => p.State == EntityState.Deleted
&& p.Entity is ModelBase))//I do have a base class for entities with a single
//"ID" property - all my entities derive from this,
//but you could use ISoftDelete here
SoftDelete(entry);
return base.SaveChanges();
}
private void SoftDelete(DbEntityEntry entry)
{
var e = entry.Entity as ModelBase;
string tableName = GetTableName(e.GetType());
Database.ExecuteSqlCommand(
String.Format("UPDATE {0} SET IsDeleted = 1 WHERE ID = @id", tableName)
, new SqlParameter("id", e.ID));
//Marking it Unchanged prevents the hard delete
//entry.State = EntityState.Unchanged;
//So does setting it to Detached:
//And that is what EF does when it deletes an item
//http://msdn.microsoft.com/en-us/data/jj592676.aspx
entry.State = EntityState.Detached;
}
方法那是我過去這樣做的方式。可能與EF5中的數據庫優先方法無關,但我現在已經開始使用存儲過程。 EF6 Code First在遷移文件中生成CreateStoredProcedure
調用。我將它們替換爲this.CreateDeleteProcedure("dbo.Foo_Delete", "[dbo].[Foos]");
- 這是對我自己的擴展方法的調用:
public static class MigrationExtensions
{
internal static string DeleteSqlFormat
{
//I also hard delete anything deleted more than a day ago in the same table
get { return "DELETE FROM {0} WHERE IsDeleted = 1 AND DATEADD(DAY, 1, DeletedAt) < GETUTCDATE(); UPDATE {0} SET IsDeleted = 1, DeletedAt = GETUTCDATE() WHERE ID = @ID;"; }
}
internal static void CreateDeleteProcedure(this DbMigration migration, string procName, string tableName)
{
migration.CreateStoredProcedure(
procName,
p => new
{
ID = p.Int(),
},
body:
string.Format(MigrationExtensions.DeleteSqlFormat, tableName)
);
}
}
+1非常好的解決方案。 –
這就是我一直在尋找的詞,「軟刪除」。是的,這對於代碼來說似乎是一個很好的解決方案。很可能,我將在存儲過程中創建一個動態查詢,並在edmx中使用存儲過程映射,並將我創建的存儲過程映射到Delete。所以當我在上下文中調用Delete時,它會自動調用我自動映射的Delete存儲過程。 – Amila
令人印象深刻的是,在尋找工作解決方案後,我找到了一個。在讓GetTableName工作時有一些小問題,你在另一篇文章中發佈的版本需要一些小的調整來編譯。但這並沒有改變這個事實,即這種軟刪除方法的確像一種魅力。 –