上一篇我們介紹了Entity Framework Core系列之DbContext(修改),這一篇我們介紹下刪除數據
修改實體的方法取決於context是否正在跟蹤需要刪除的實體。
下面的示例中context獲得了需要刪除的實體對象,所以context會開始追蹤這個實體。DbContext.Remove方法會將實體的EntityState設置成deleted。
context.Remove(context.Authors.Single(a => a.AuthorId == 1)); context.SaveChanges();
當SaveChanges被調用時,數據庫生成並執行delete語句
exec sp_executesql N'SET NOCOUNT ON; DELETE FROM [Authors] WHERE [AuthorId] = @p0; SELECT @@ROWCOUNT; ',N'@p0 int',@p0=1
這種方法實際上執行了兩個sql語句,一個用於從數據庫檢索實體,另一個用於刪除實體,您可以使用存根來表示要刪除的實體,從而停止從數據庫檢索的實體:
using (var context = new EFCoreContext()) { var author = new Author { AuthorId = 1 }; context.Remove(author); context.SaveChanges(); }
存根需要的唯一屬性是主鍵值。
設置EntityState
可以通過EntityEntry顯式地設置要刪除的實體的EntityState的屬性值
using (var context = new EFCoreContext()) { var author = new Author { AuthorId = 1 }; context.Entry(author).State = EntityState.Deleted; context.SaveChanges(); }
多個相關實體
如果需要刪除的實體有關聯的數據,那就看這些關系是如何配置的,一個完全定義的關系將具有一個級聯引用約束集來刪除或SetNull,通過Fluent API配置的關系也是如此。在這些情況下,您可以刪除主體並讓數據庫處理相關的行。當引用約束動作被設置為NoAction時,您需要顯式地處理所有相關數據。下一個示例演示了在不包含外鍵屬性的模型上配置的關系:
public class Author { public int AuthorId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public ICollection<Book> Books { get; set; } } public class Book { public int BookId { get; set; } public string Title { get; set; } }
默認情況下,此關系被配置為可選的,引用約束操作選項被配置為NoAction。此外,EF Core引入了一個影子屬性來表示外鍵。它被命名為AuthorId,並應用於Book實體,由於關系是可選的,所以AuthorId屬性可以為nullable。為了刪除Author,你需要刪除每個Book和Author之間的關系。代碼如下:
using (var context = new EFCoreContext()) { var author = context.Authors.Single(a => a.AuthorId == 1); var books = context.Books.Where(b => EF.Property<int>(b, "AuthorId") == 1); foreach (var book in books) { author.Books.Remove(book); } context.Remove(author); context.SaveChanges(); }
從數據庫中檢索Author,和它相關的Books也就被檢索出來然后再逐一被remove出集合,然后執行context.Remove(author),最后結果會使相關的Book中的AuthorId設置成null。
exec sp_executesql N'SET NOCOUNT ON; UPDATE [Books] SET [AuthorId] = @p0 WHERE [BookId] = @p1; SELECT @@ROWCOUNT; UPDATE [Books] SET [AuthorId] = @p2 WHERE [BookId] = @p3; SELECT @@ROWCOUNT; UPDATE [Books] SET [AuthorId] = @p4 WHERE [BookId] = @p5; SELECT @@ROWCOUNT; ',N'@p1 int,@p0 int,@p3 int,@p2 int,@p5 int,@p4 int',@p1=1,@p0=NULL,@p3=2,@p2=NULL,@p5=3,@p4=NULL
exec sp_executesql N'SET NOCOUNT ON; DELETE FROM [Authors] WHERE [AuthorId] = @p6; SELECT @@ROWCOUNT; ',N'@p6 int',@p6=1
數據庫執行了四次操作:查詢Author,查詢Book,更新Book,刪除Author,因此,使用引用完整性約束將外鍵設置為null或刪除依賴項是一個好主意o。