最近,在使用通用权限管理系统开发一个项目,数据库是MSSQL,登录时出现一个错误,发现是记录登录日志时出现的错误。
由于每次登录,都会记录登录日志,就是在记录日志时出现了错误。
先把错误截图
可以看出与记录登录日志的表BaseLoginLog的ID有关系,打开该表
发现该表的ID是nvarchar(50)类型,查询一下该表的数据,截图如下
可看到,ID实际存储的是GUID类型数据,然后我在调试底层代码,找到三个地方:
1 /// <summary> 2 /// 记录登录日志 3 /// </summary> 4 /// <param name="systemCode">系统编码</param> 5 /// <param name="userId">用户ID</param> 6 /// <param name="userName">登录用户名</param> 7 /// <param name="ipAddress">IP地址</param> 8 /// <param name="macAddress">MAC地址</param> 9 /// <param name="loginStatus">登录结果</param> 10 /// <returns></returns> 11 public static string AddLog(string systemCode, string userId, string userName, string ipAddress, string macAddress, string loginStatus) 12 { 13 BaseLoginLogEntity entity = new BaseLoginLogEntity(); 14 entity.SystemCode = systemCode; 15 entity.UserId = userId; 16 entity.UserName = userName; 17 entity.IPAddress = ipAddress; 18 entity.MACAddress = macAddress; 19 entity.LoginStatus = loginStatus; 20 entity.CreateOn = DateTime.Now; 21 string tableName = BaseLoginLogEntity.TableName; 22 if (BaseSystemInfo.BusinessDbType == CurrentDbType.Oracle) 23 { 24 tableName += DateTime.Now.ToString("yyyyMM"); 25 } 26 BaseLoginLogManager loginLogManager = new BaseLoginLogManager(tableName); 27 return loginLogManager.Add(entity, true, false); 28 }
1 /// <summary> 2 /// 添加, 这里可以人工干预,提高程序的性能 3 /// </summary> 4 /// <param name="entity">实体</param> 5 /// <param name="identity">自增量方式,表主键是否采用自增的策略</param> 6 /// <param name="returnId">返回主键,不返回程序允许速度会快,主要是为了主细表批量插入数据优化用的</param> 7 /// <returns>主键</returns> 8 public string Add(BaseLoginLogEntity entity, bool identity = false, bool returnId = false) 9 { 10 this.Identity = identity; 11 this.ReturnId = returnId; 12 return this.AddObject(entity); 13 }
1 /// <summary> 2 /// 添加登录日志 多数据库支持 3 /// </summary> 4 /// <param name="entity">登录日志实体</param> 5 public string AddObject(BaseLoginLogEntity entity) 6 { 7 string key = string.Empty; 8 if (!string.IsNullOrWhiteSpace(entity.Id)) 9 { 10 key = entity.Id.ToString(); 11 } 12 SQLBuilder sqlBuilder = new SQLBuilder(DbHelper, this.Identity, this.ReturnId); 13 sqlBuilder.BeginInsert(this.CurrentTableName, this.PrimaryKey); 14 if (!this.Identity) 15 { 16 // 这里已经是指定了主键了,所以不需要返回主键了 17 sqlBuilder.ReturnId = false; 18 sqlBuilder.SetValue(this.PrimaryKey, entity.Id); 19 } 20 else 21 { 22 if (!this.ReturnId && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2)) 23 { 24 if (DbHelper.CurrentDbType == CurrentDbType.Oracle) 25 { 26 sqlBuilder.SetFormula(this.PrimaryKey, "SEQ_" + this.CurrentTableName.ToUpper() + ".NEXTVAL "); 27 } 28 if (DbHelper.CurrentDbType == CurrentDbType.DB2) 29 { 30 sqlBuilder.SetFormula(this.PrimaryKey, "NEXT VALUE FOR SEQ_" + this.CurrentTableName.ToUpper()); 31 } 32 } 33 else 34 { 35 if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2)) 36 { 37 BaseSequenceManager sequenceManager = new BaseSequenceManager(DbHelper); 38 entity.Id = sequenceManager.Increment(this.CurrentTableName); 39 sqlBuilder.SetValue(this.PrimaryKey, entity.Id); 40 } 41 } 42 } 43 this.SetObject(sqlBuilder, entity); 44 sqlBuilder.SetDBNow(BaseLoginLogEntity.FieldCreateOn); 45 if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.SqlServer || DbHelper.CurrentDbType == CurrentDbType.Access)) 46 { 47 key = sqlBuilder.EndInsert().ToString(); 48 } 49 else 50 { 51 sqlBuilder.EndInsert(); 52 } 53 if (this.Identity && (DbHelper.CurrentDbType == CurrentDbType.Oracle || DbHelper.CurrentDbType == CurrentDbType.DB2)) 54 { 55 return entity.Id.ToString(); 56 } 57 return key; 58 }
从代码中可以看出,并没有对ID进行赋值的地方,本来想将底层代码改一下,将生成一个GUID后作为ID值加入进去,后来考虑到这么做不是很好,
考虑到可以直接改一下数据库中的字段类型,将原来的nvarchar(50)类型改为uniqueidentifier类型,并设置了默认值(newid())。
如下图:
再次运行项目,错误不在出现了。
大家在使用通用权限管理系统开发项目中,如果遇到一些问题,可加入“通用权限管理系统”QQ交流群:371168832,一起交流、共同提高。