今天没有事,想着用.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; }
}
我们写个方法测试一下
[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 = "插入失败" };
}
在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 = "插入失败" };
}
效果如下:
总之,希望更新级联插入,自动维护中间表。