Entity Framework Core系列之DbContext(刪除)


上一篇我們介紹了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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM