为了防止误删除,通用权限管理里有2个方法可以阻止误删除,1个是打删除标志的方法,另外一个把数据备份到被删除表里(另外一个表里),喜欢用哪个方式要看开发人员的选择看项目的性质灵活运用,觉得哪个做法好就可以用哪个方法,删除标志的方法虽然简单但是过滤数据很麻烦而且数据库量超大后数据库的性能有明显的影响。
把被删除的数据备份到另外一个表虽然程序处理繁杂一些但是数据库的性能影响会很小数据库的性能一直会比较高一些,有对数据有洁癖的人适合用这个方式。通过下面的例子程序可以模仿通用权限管理的防止误删除功能,把自己的业务系统都进行改造,思路思想也都可以借鉴一下。
天气凉爽、总算有心情写个博客了,把被误删除的数据需要恢复过来时不是专业的数据库管理员,那是一个很艰难的事情,而且知道哪些数据被删除了也不是那么简单的事情,写个数据库触发器是一个不错的处理方法,把当前要被删除的数据都存放到相同结构的另外一个备份表里。 对于数据的备份功能自增量主键而言GUID为主键的表处理起来更简单一些。
被删除的表,主键最好不是自增量,因为需要保留原始数据的主键,否则数据库很难恢复或者涉及到主细表的问题等等,所以被删除的表的主键建议不要用则增量。
我们在角色管理界面上选中2条数据库,在调试模式下,然后按删除,看程序的运行效果如何?
已经被放到被删除的表里来了,主键也没被篡改,非常不错。
这个是为了特意在测试调试模式下把被删除的数据转移到另外一个表的做法。
下面是没有采用数据库触发器的方式,对删除的表进行数据备份的方法。
1:这里设计到备份表的主键问题。
2:数据库事务问题,要么成功,要么失败,要么全成功。
3:不要数据库触发器,而是用程序去实现。
4:兼容多种数据库。
5:下出来的代码量非常小,不能有过于繁琐的代码,需要重复利用很多现有的类库。
6:由于系统同时支持多个子系统,意思是有可能是多个系统的不同的角色表,所以要支持多系统的权限管理说白了就是多表的操作,不只是固定的2个表。
/// 批量删除角色
/// </summary>
/// <param name="userInfo"> 用户 </param>
/// <param name="ids"> 主键数组 </param>
/// <returns> 影响行数 </returns>
public int BatchDelete(BaseUserInfo userInfo, string[] ids)
{
// 写入调试信息
#if (DEBUG)
int milliStart = BaseBusinessLogic.StartDebug(userInfo, MethodBase.GetCurrentMethod());
#endif
// 加强安全验证防止未授权匿名调用
#if (!DEBUG)
LogOnService.UserIsLogOn(userInfo);
#endif
int returnValue = 0;
using (IDbHelper dbHelper = DbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType))
{
try
{
dbHelper.Open(UserCenterDbConnection);
// 开始数据库事务
dbHelper.BeginTransaction();
string tableName = BaseRoleEntity.TableName;
if (! string.IsNullOrEmpty(BaseSystemInfo.SystemCode))
{
tableName = BaseSystemInfo.SystemCode + " Role ";
}
BaseRoleManager roleManager = new BaseRoleManager(dbHelper, userInfo, tableName);
// 这里是直接删除功能的实现
// returnValue = roleManager.BatchDelete(ids);
BaseRoleEntity roleEntity = null;
// 把删除的记录放到被删除的表里(表名后面加了后缀Deleted,也可以放在另外一个数据库里也可以的)
BaseRoleManager roleDeletedManager = new BaseRoleManager(dbHelper, userInfo, tableName + " Deleted ");
foreach ( var id in ids)
{
// 逐个删除,逐个备份
roleEntity = roleManager.GetEntity(id);
// 先添加到被删除的表里,这时候原先数据的主键需要保留的,否则恢复数据时可能会乱套
roleDeletedManager.Add(roleEntity);
// 数据备份好后再进行删除处理
returnValue += roleManager.Delete(id);
}
// 提交数据库事务
BaseLogManager.Instance.Add(dbHelper, userInfo, serviceName, AppMessage.RoleService_BatchDelete, MethodBase.GetCurrentMethod());
dbHelper.CommitTransaction();
}
catch (Exception ex)
{
// 撤销数据库事务
dbHelper.RollbackTransaction();
BaseExceptionManager.LogException(dbHelper, userInfo, ex);
throw ex;
}
finally
{
dbHelper.Close();
}
}
// 写入调试信息
#if (DEBUG)
BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(), milliStart);
#endif
return returnValue;
}
通用权限管理系统的架构,几乎没修改几行代码,就可以实现用户的删除数据是备份数据的需求,虽然没数据库触发器处理那么简单,但是程序的灵活性很强,可阅读性、可调试性、多数据库的兼容性等等方面,还是有明显的优点的。
删除处理的方法还可以写在代码生成器里,这样所有的删除操作,都可以实现数据库的备份了,又简单又好用,也不用动脑子了,很省事。