欢迎来到《FreeSql.Repository 仓储模式》系列文档,本系列文档专注介绍 【仓储+工作单元】 的使用方式。完整文档请前往 wiki 中心:https://github.com/dotnetcore/FreeSql/wiki

前面说到,仓储模式推荐使用导航属性,联表查询、子表查询、级联加载都已得到解决,本文继续配置导航属性之后,级联保存如何使用。

实践发现,N对1 不适合做级联保存。保存 Topic 的时候把 Type 信息也保存?我个人认为自下向上保存的功能太不可控了,FreeSql 目前不支持自下向上保存。因此下面我们只讲 OneToMany/ManyToMany 级联保存。至于 ManyToOne/OneToOne 级联保存使用手工处理,更加安全可控。

OneToMany

方式一:完整保存,对比表已存在的数据,计算出添加、修改、删除执行

递归保存导航属性不安全,不可控,并非技术问题,而是出于安全考虑,提供了手工完整保存的方式。

var repo = fsql.GetRepository<Type>();
var type = new Type
{
    name = "c#",
    Topics = new List<Topic>(new[] {        new Topic
        {
            ...
        }
    })
};
repo.Insert(type);
repo.SaveMany(type, "Topics"); //手工完整保存 Topics

请确认机制:

  • 有可能删除表已存在的数据,确认?
  • 当 Topics 属性为 Empty 时,删除 type 存在的 Topics 所有表数据,确认?
  • 保存 Topics 的时候,不、不、不保存 Childs[0-..] 的下级集合属性,只保存 Topics 当前层级,确认?

方法二:追加保存,不删除表已存在的数据

此方式建议用在不太重要的功能,或者测试数据添加

var repo = fsql.GetRepository<Type>();
repo.DbContextOptions.EnableAddOrUpdateNavigateList = true;
repo.DbContextOptions.NoneParameter = true;
repo.Insert(new Type
{
    name = "c#",
    Topics = new List<Topic>(new[] {        new Topic
        {
            ...
        }
    })
});

请确认机制:

  • 不删除表已存在的数据,确认?
  • 当 Topics 属性为 Empty 时,不做任何操作,确认?
  • 保存 Childs 的时候,还会保存 Childs[0-..] 的下级集合属性,向下18层,确认?

向下18层的意思,比如【类型】表,下面有集合属性【文章】,【文章】下面有集合属性【评论】。

保存【类型】表对象的时候,他会向下检索出集合属性【文章】,然后如果【文章】被保存的时候,再继续向下检索出集合属性【评论】。一起做 InsertOrUpdate 操作。

ManyToMany

配置好的 ManyToMany 多对多导航属性,支持级联保存,并且只有一种机制:完整保存。

开启 EnableAddOrUpdateNavigateList 或者 SaveMany 都是完整保存。