• 【EF Core】如何忽略影响导航属性(级联)


    EF更新和插入时如何忽略更新导航属性

    1. 使用Ignore方法:
    modelBuilder.Entity<Blog>()
        .Ignore(b => b.Posts);
    
    • 1
    • 2
    1. 使用HasNoKey方法:
    modelBuilder.Entity<Blog>()
        .HasNoKey();
    
    • 1
    • 2
    1. 使用HasNoNavigation方法:
    modelBuilder.Entity<Blog>()
        .HasNoNavigation(b => b.Posts);
    
    • 1
    • 2
    1. 使用HasNoRelationship方法:
    modelBuilder.Entity<Blog>()
        .HasNoRelationship(b => b.Posts);
    
    • 1
    • 2

    级联删除

    删除主体/父实体

    请考虑此简单模型,其中 Blog 是与 Post(依赖实体/子实体)的关系中的主体/父实体。 Post.BlogId 是一个外键属性,其值必须与该文章所属博客中的 Blog.Id 主键匹配。

    public class Blog
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public IList<Post> Posts { get; } = new List<Post>();
    }
    
    public class Post
    {
        public int Id { get; set; }
    
        public string Title { get; set; }
        public string Content { get; set; }
    
        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    按照约定,由于 Post.BlogId 外键属性是不可为 null 的,因此该关系被配置为必需的。 默认情况下,所需的关系配置为使用级联删除。 要详细了解建模关系,请参阅关系。

    删除博客时,所有文章都将被级联删除。 例如:

    using var context = new BlogsContext();
    
    var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
    
    context.Remove(blog);
    
    context.SaveChanges();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    SaveChanges 以 SQL Server 为例,生成以下 SQL:

    -- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
    SET NOCOUNT ON;
    DELETE FROM [Posts]
    WHERE [Id] = @p0;
    SELECT @@ROWCOUNT;
    
    -- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
    SET NOCOUNT ON;
    DELETE FROM [Posts]
    WHERE [Id] = @p0;
    SELECT @@ROWCOUNT;
    
    -- Executed DbCommand (2ms) [Parameters=[@p1='1'], CommandType='Text', CommandTimeout='30']
    SET NOCOUNT ON;
    DELETE FROM [Blogs]
    WHERE [Id] = @p1;
    SELECT @@ROWCOUNT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    断开关系

    我们不会删除博客,而是断开每篇文章与其博客之间的关系。 为此,可将每篇文章的引用导航 Post.Blog 设置为 null:

    using var context = new BlogsContext();
    
    var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
    
    foreach (var post in blog.Posts)
    {
        post.Blog = null;
    }
    
    context.SaveChanges();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    还可通过从 Blog.Posts 集合导航中删除每篇文章内容来断开关系:

    using var context = new BlogsContext();
    
    var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
    
    blog.Posts.Clear();
    
    context.SaveChanges();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    无论哪种情况,结果都一样:没有删除博客,但是删除了不再与任何博客关联的文章:

    -- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
    SET NOCOUNT ON;
    DELETE FROM [Posts]
    WHERE [Id] = @p0;
    SELECT @@ROWCOUNT;
    
    -- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
    SET NOCOUNT ON;
    DELETE FROM [Posts]
    WHERE [Id] = @p0;
    SELECT @@ROWCOUNT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    删除不再与任何主体/依赖实体关联的实体这一行为被称作“删除孤立项”。

    级联删除和删除孤立项是密切相关的。 当断开与所需的主体/父实体之间的关系时,两者都将导致删除依赖实体/子实体。 对于级联删除,由于主体/父实体本身已删除,因此发生了这种断开。 对于孤立项,主体/父实体仍然存在,但不再与依赖实体/子实体相关。

    配置级联行为

    使用 OnModelCreating 中的 OnDelete 方法按关系配置级联行为。 例如:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<Blog>()
            .HasOne(e => e.Owner)
            .WithOne(e => e.OwnedBlog)
            .OnDelete(DeleteBehavior.ClientCascade);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    OnDelete 从公认地令人混淆的 DeleteBehavior 枚举中接受一个值。 该枚举既定义了 EF Core 在跟踪实体上的行为,又定义了使用 EF 创建架构时数据库中级联删除的配置。

    来源

    EF更新和插入时如何忽略更新导航属性
    级联删除

  • 相关阅读:
    dvaJs在react 项目中的简单使用
    搞懂 MySql 的架构和执行流程
    用核心AI资产打造稀缺电竞体验,顺网灵悉背后有一盘大棋
    学习Java到底要不要报班?自学可以吗?
    超级英雄云计算的技术之旅
    【获取当前月时间】elementul日期选择器在页面一进来直接获取到本月1号到当前日期的方法【详细注释】
    C++求解汉明距离
    springboot2 --- 基础入门
    PIL中的P模式、P模式转为L模式
    管理学家杂志管理学家杂志社管理学家编辑部2022年第12期目录
  • 原文地址:https://blog.csdn.net/weixin_44231544/article/details/133274003