private int FindMaxSerialNo(string cycleModel, DataTable dt, DateTime now, SerialChunk Serialchunk, int NoStart, int NoLen, SerialChunk Datechunk, int DateStart, int DateLen) { int max = -1; //找出最大的序列码 if (dt.Rows.Count > 0) { //从已存在的记录中找出有效的最大序列码 if (cycleModel == "none" || string.IsNullOrWhiteSpace(cycleModel)) { //序列码不循环时 for (int i = 0; i < dt.Rows.Count; i++) { string str = dt.Rows[i][0].ToString(); try { int cu; if (Serialchunk.Varlen) { cu = int.Parse(str.Substring(NoStart, str.Length - NoStart)); } else { cu = int.Parse(str.Substring(NoStart, NoLen)); } max = max > cu ? max : cu; } catch { continue; } } return(max); } string format = ""; switch (cycleModel) { case "day": { format = "yyyyMMdd"; break; } case "month": { format = "yyyyMM"; break; } case "year": { format = "yyyy"; break; } case "hour": { format = "yyyyMMddHH"; break; } case "minute": { format = "yyyyMMddHHmm"; break; } } //序列码循环时 DateTime dtcp = DateTime.ParseExact(now.ToString(format), format, null); DateTime dttmp; for (int i = 0; i < dt.Rows.Count; i++) { string str = dt.Rows[i][0].ToString(); try { dttmp = DateTime.ParseExact(DateTime.ParseExact(str.Substring(DateStart, DateLen), Datechunk.DateFormate, null).ToString(format), format, null); if (dttmp == dtcp) { int cu; if (Serialchunk.Varlen) { cu = int.Parse(str.Substring(NoStart, str.Length - NoStart)); } else { cu = int.Parse(str.Substring(NoStart, NoLen)); } max = max > cu ? max : cu; } } catch { continue; } } } return(max); }
public string NewSNO(IDbAccess iDb, string tableName, string colName, List <SerialChunk> chunks) { ValiAndPreDealPara(tableName, colName, chunks); string key = GeneSNOKey(tableName, colName, chunks); object lockobj = GetSNOLock(tableName, colName, chunks); lock (lockobj) { DateTime now = DateTime.Now; object obj; bool b = ht_SNO_nos.TryGetValue(key, out obj); string cycleModel = ""; //序列体循环模式 SerialChunk Serialchunk = null; //序列块 SerialChunk Datechunk = null; //日期循环块 int NoStart = 0; //序列块开始索引 int NoLen = -1; //序列块长度 int SerialTotalLen = 0; //序列体总长度 int DateStart = 0; //日期块开始索引 int DateLen = 0; //日期块长度 int max = -1; //有效的最大序列码 //第一次循环检查 for (int i = 0; i < chunks.Count; i++) { var chunk = chunks[i]; if (chunk.Type == "SerialNo") { Serialchunk = chunk; cycleModel = chunk.CycleModel; for (int ii = 0; ii < chunks.Count; ii++) { var chu = chunks[ii]; if (chu.Type != "SerialNo") { NoStart += chu.Len; SerialTotalLen += chu.Len; } else { if (chu.Varlen) { //如果序列块变长的 NoLen = -1; SerialTotalLen = -1; } else { //序列块是定长的 NoLen = chu.Len; SerialTotalLen += chu.Len; } } } } else if (chunk.Type == "DateTime" && chunk.Incyle) { Datechunk = chunk; DateLen = chunk.Len; for (int ii = 0; ii < i; ii++) { var chu = chunks[ii]; DateStart += chu.Len; } } } if (!b) { //缓存中没有当前类型的编号 string likeStr = "";//去后台查询已经存在的匹配编号时用 //第二次循环开始生成匹配串 for (int j = 0; j < chunks.Count; j++) { var chunk = chunks[j]; if (chunk.Type == "Text") { likeStr += chunk.TextVal; } else if (chunk.Type == "SerialNo") { if (chunk.Varlen) { likeStr += "%"; } else { for (int i = 0; i < chunk.Len; i++) { likeStr += "_"; } } } else if (chunk.Type == "DateTime") { if (cycleModel == "none" || string.IsNullOrWhiteSpace(cycleModel)) { //序列码不循环 for (int i = 0; i < chunk.Len; i++) { likeStr += "_"; } } else { //序列码循环 if (!chunk.Incyle) { //当前日期不在循环中 for (int i = 0; i < chunk.Len; i++) { likeStr += "_"; } } else { //当前日期在循环中 string str = now.ToString(chunk.DateFormate); if (str.Length != chunk.Len) { throw new Exception("格式化当前日期后的长度与制定的日期块所占长度不一致:[" + str + "][" + chunk.Len + "]"); } likeStr += now.ToString(chunk.DateFormate); } } } } //根据生成的序列号匹配串去后台查找相近的编号 string sql = string.Format("select distinct {0} from {1} where {0} like '{2}'", colName, tableName, likeStr); DataTable dt = iDb.GetDataTable(sql); max = FindMaxSerialNo(cycleModel, dt, now, Serialchunk, NoStart, NoLen, Datechunk, DateStart, DateLen); } else { //缓存中有当前类型的编号 DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn()); DataRow row = dt.NewRow(); row[0] = obj.ToString(); dt.Rows.Add(row); max = FindMaxSerialNo(cycleModel, dt, now, Serialchunk, NoStart, NoLen, Datechunk, DateStart, DateLen); } //根据已经找到的有效最大序列码进行编号的自动生成 string res = ""; for (int j = 0; j < chunks.Count; j++) { var chunk = chunks[j]; if (chunk.Type == "Text") { res += chunk.TextVal; } else if (chunk.Type == "SerialNo") { string no = ""; if (max == -1) { no = chunk.Start.ToString(); if (!chunk.Varlen) { no = no.PadLeft(chunk.Len, '0'); } } else { no = (max + chunk.Incr).ToString(); if (!chunk.Varlen) { no = no.PadLeft(chunk.Len, '0'); } } if (!chunk.Varlen) { if (no.Length != chunk.Len) { throw new Exception("生成的序列码和指定的序列码的长度不一致[" + no.ToString() + "][" + chunk.Len + "]!"); } } res += no; } else if (chunk.Type == "DateTime") { string dtstr = now.ToString(chunk.DateFormate); if (dtstr.Length != chunk.Len) { throw new Exception("生成的日期块的长度与指定的长度不一致[" + dtstr + "][" + chunk.Len + "]!"); } res += dtstr; } } if (ht_SNO_nos.TryGetValue(key, out obj)) { ht_SNO_nos[key] = res; } else { ht_SNO_nos.TryAdd(key, res); } return(res); } }