• 关于SqlSugar的多对多的级联插入的问题(无法获取集合属性的id,导致无法维护中间表)


    发现问题:

    今天没有事,想着用.Net Core WebApi写一个RBAC的小Demo,
    Demo很简单,主要就是Role和Permission,User和Role的两个多对多的关系,也就5张表的事。
    打算使用ORM来简化操作,故使用SqlSugar来帮助开发。但在级联插入时好像出现了一些问题。

    现有模型,和生成的表如下

    [SugarTable(tableName:"t_permisssion")]
     public class Permission
     {
         [SugarColumn(IsPrimaryKey =true,IsIdentity =true)]
         public long Id { get; set; }
    
         [SugarColumn(SerializeDateTimeFormat = "yyyy-mm-dd hh:mm:ss")]
         public DateTime Create_Time { get; set; }
    
         public string Name { get; set; }
    
         public string Desc { get; set; }
    
         public string Type { get; set; }
    
         public string Create_Emp { get; set; }
    
         [Navigate(typeof(Role_Permisssion),nameof(Role_Permisssion.Permission_Id),nameof(Role_Permisssion.Role_Id))]
         public List<Role> roles { get; set; }
    
     }
    [SugarTable(tableName:"t_roles")]
    public class Role
      {
          [SugarColumn(IsPrimaryKey =true,IsIdentity =true)]
          public long Id { get; set; }
    
    
          public string Name { get; set; }
    
          public string Desc { get; set; }
    
          [SugarColumn(SerializeDateTimeFormat = "yyyy-mm-dd hh:mm:ss")]
    
          public string Create_Time { get; set; }
    
          public string Create_Emp {get;set;}
    
          
          [Navigate(typeof(Role_Permisssion),nameof(Role_Permisssion.Role_Id),nameof(Role_Permisssion.Permission_Id))]
          public List<Permission> permissions { get; set; }
      }
    [SugarTable(tableName:"t_role_permission")]
    public class Role_Permisssion
    {
        [SugarColumn(IsPrimaryKey =true)]
        public long Role_Id { get; set; }
    
        [SugarColumn(IsPrimaryKey = true)]
        public long Permission_Id { get; set; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    请添加图片描述
    我们写个方法测试一下

     [HttpPost]
            public StandResult<object> Create_Role([FromBody]Role role)
            {
                SqlSugar.ISubInsertable<Role> res = scoper.GetTool().ScopedContext.Insertable(role).AddSubList(it => it.permissions);
    
                int count = (int)res.ExecuteCommand();
                //SqlSugar好像不会去自动维护中间表,所以要自己来获取自增ID来维护中间表
                List<Role_Permisssion> list = new List<Role_Permisssion>();
    
                role.permissions.ForEach(item =>
                {
                	//在测试中Role.Id可以正确获取生成的自增ID,而其中的Permission集合的自增ID却无法获取
                    list.Add(new Role_Permisssion() { Role_Id = role.Id, Permission_Id = item.Id });
                });
    
                scoper.GetTool().Insertable(list).ExecuteCommand();
    
                if (count >= 1)
                    return new StandResult<object>() { data = count,Status = 1,Message = "插入成功"};
    
                return new StandResult<object>() { data = count, Status = 0, Message = "插入失败" };
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在swagger中测试插入,(这里的参数id是没有用的,它们实际上生成的是自增值)
    请添加图片描述
    请添加图片描述
    这一点还是有点问题的,一般的ORM应该自动去维护中间表。故多对多的级联操作还是很重要的,毕竟可以简化开发过程。

    目前的替代方法

    当然,上面的问题是可以规避的,不过是要把对象的插入拆分开来,分别来获取其自增值
    代码如下:

     public StandResult<object> Create_Role([FromBody]Role role)
    {
        var res = scoper.GetTool().ScopedContext.Insertable(role);
    	//先插入Role,拿到自增Id
        long count = res.ExecuteReturnBigIdentity();
    
        List<Role_Permisssion> list = new List<Role_Permisssion>();
        //再插入role中的permission集合,循环插入来获取自增值,并维护中间类的集合
        role.permissions.ForEach(item => {
            var res2 = scoper.GetTool().ScopedContext.Insertable(item).ExecuteReturnBigIdentity();
            list.Add(new Role_Permisssion() { Role_Id = count, Permission_Id = res2 });
        });
        //最后再插入中间类的集合
        scoper.GetTool().Insertable(list).ExecuteCommand();
    
        if (count >= 1)
            return new StandResult<object>() { data = count,Status = 1,Message = "插入成功"};
    
        return new StandResult<object>() { data = count, Status = 0, Message = "插入失败" };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    效果如下:
    请添加图片描述
    总之,希望更新级联插入,自动维护中间表。

  • 相关阅读:
    json-server搭建mock服务
    Soc系统级芯片
    自己最好的canny实现(c#)
    操作教程|如何将DataEase开源工具嵌入第三方系统?
    Today‘s文章_signature
    应对铜价飙升,慧能泰推出超高性价比240W五芯线专用eMarker芯片
    基于 CoreDNS 和 K8s 构建云原生场景下的企业级 DNS
    Java-基于SSM+JSP的医院挂号管理系统
    Python内置函数12——map
    java校验字符串只包含数字
  • 原文地址:https://blog.csdn.net/jamenu/article/details/125463692