最近,在使用通用權限管理系統開發一個項目,數據庫是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,一起交流、共同提高。