• 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。

  • 相关阅读:
    关于HTML5画布canvas的功能
    HTML5新标签介绍
    为HTML5添加新样式标签
    iOS开发相关图书推荐
    Android相关图书推荐
    C语言相关图书推荐
    C#相关图书推荐
    C++相关图书推荐
    JavaScript相关图书推荐
    Java相关书籍推荐
  • 原文地址:https://www.cnblogs.com/yixuanhan/p/9272741.html
Copyright © 2020-2023  润新知