版本更新后,更新分表数据时,分表名的时间后缀出现了( TableName_2026_07_2026_07 ) 返回
SqlSugar
待处理
5
248
悬赏:5 飞吻
分表名使用了自定义的写法(BasicSplitTableService : ISplitTableService)。
版本从5.1.4.126(旧版) 升级到了5.1.4.216(新版)。旧版BasicSplitTableService 时运行3年都正常。升级新版本后,创建、查询、删除都正常,但是更新分表数据时报错,出现了表名OperationRecord_2026_07_2026_07 的情况。更新的写法如下
DB.Updateable<OperationRecord>(records).UpdateColumns(UpdateColumns).Where(s => s.State != EnumExecuteState.Completed).WhereColumns(UpdateWhere).SplitTable(t => t.Take(3)).ExecuteCommandAsync();
请大佬抽空看看。BasicSplitTableService 代码如下
public class BasicSplitTableService : ISplitTableService{ private IFormatProvider TimeFormatProvider = new CultureInfo("zh-CN", true); public List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo entityInfo, List<DbTableInfo> tableInfos)
{ List<SplitTableInfo> infos = new List<SplitTableInfo>(); foreach (var table in tableInfos.Where(s => s.Name.StartsWith(entityInfo.DbTableName)))
{ string tbName = table.Name; string splitInfo = tbName.Replace($"{entityInfo.DbTableName}_", string.Empty); DateTime tbTime = DateTime.MinValue; if (!DateTime.TryParseExact(splitInfo, "yyyy", TimeFormatProvider, DateTimeStyles.None, out tbTime)
&& !DateTime.TryParseExact(splitInfo, "yyyy_MM", TimeFormatProvider, DateTimeStyles.None, out tbTime)
&& !DateTime.TryParseExact(splitInfo, "yyyy_MM_dd", TimeFormatProvider, DateTimeStyles.None, out tbTime))
{ if (splitInfo.Contains("_Season"))
{ string[] strs = splitInfo.Split("_Season"); if (strs.Length > 1)
{ int season = int.Parse(strs[1]); tbTime = new DateTime(int.Parse(strs[0]), 1, 1).AddMonths(season * 3);
}
} if (splitInfo.Contains("_Week"))
{ string[] strs = splitInfo.Split("_Week"); if (strs.Length > 1)
{ int week = int.Parse(strs[1]); tbTime = new DateTime(int.Parse(strs[0]), 1, 1).AddDays(week * 7);
}
} if (splitInfo.Contains("_Half"))
{ string[] strs = splitInfo.Split("_Half"); if (strs.Length > 1)
{ int half = int.Parse(strs[1]); tbTime = new DateTime(int.Parse(strs[0]), 1, 1).AddMonths(half * 6);
}
}
} infos.Add(new SplitTableInfo
{
TableName = table.Name,
Date = tbTime,
});
} return infos.OrderByDescending(t => t.Date).ToList();
} public object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
{ EntityColumnInfo splitColumn = entityInfo.Columns.FirstOrDefault(s => s.PropertyInfo.GetCustomAttribute<SplitFieldAttribute>() != null); if (splitColumn == null) return null; return splitColumn.PropertyInfo.GetValue(entityValue);
} public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo)
{ var attribute = entityInfo.Type.GetCustomAttribute<SplitTableAttribute>(); if (attribute == null) return entityInfo.DbTableName; return GetTableName(db, entityInfo, attribute.SplitType, DateTime.Now);
} public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType)
{ return GetTableName(db, entityInfo, splitType, DateTime.Now);
} public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
{ DateTime time; if (fieldValue is DateTime t1) time = t1; else if (fieldValue is DateTimeOffset t2) time = t2.UtcDateTime; else
throw new NotImplementedException("自定义分表字段仅支持DateTime/DateTimeOffset类型!"); switch (splitType)
{ case SplitType.Year: return $"{entityInfo.DbTableName}_{time:yyyy}"; case SplitType.Month: return $"{entityInfo.DbTableName}_{time:yyyy_MM}"; case SplitType.Day: return $"{entityInfo.DbTableName}_{time:yyyy_MM_dd}"; case SplitType.Week:
{ DateTime start = new DateTime(time.Year, 1, 1); var days = (int)((time.Date - start.Date).TotalDays); return $"{entityInfo.DbTableName}_{time.Year}_Week{(days / 7)}";
} case SplitType.Season: return $"{entityInfo.DbTableName}_{time.Year}_Season{((time.Month - 1) / 3)}"; case SplitType.Month_6: return $"{entityInfo.DbTableName}_{time.Year}_Half{((time.Month - 1) / 6)}"; default: return $"{entityInfo.DbTableName}_{time:yyyy}";
}
}
}
热忱回答(5)
-
fate sta VIP0
2周前重写的GetAllTables 看一下返回的值哪有问题
0 回复 -
fate sta VIP0
2周前.Where(s => s.State != EnumExecuteState.Completed)
批量更新,可能不支持这个where。只能用wherecolumns
0 回复 -
Sephiroth VIP0
2周前@fate sta: 你好,我源码调试了一下 。在
SplitTableUpdateProvider<T> 这个类里,GetSqlObj(KeyValuePair<string, List<SugarParameter>> keyValuePair, string asName)这个方法里拼接sql出的问题。
在 sql = Regex.Replace(sql, updateobj.EntityInfo.DbTableName, asName, RegexOptions.IgnoreCase); 这一行正则执行之前表名是对的 Data_OperationRecord_2026_07。执行后表名被替换成了 Data_OperationRecord_2026_07_2026_07

0 回复 -
Sephiroth VIP0
2周前@fate sta: 你好,我发现是是2026年4月22日的提交,对SplitTableUpdateProvider<T>这个文件的修改导致的问题。 git提交Id是 380d5ada .
我把git版本回退到26年4月22号之前的版本,比如5.1.4.210版本,写法测试都是正常的。包括你说的
.Where(s => s.State != EnumExecuteState.Completed)
也都是支持的,生成的sql里有这个条件,执行正常。但是 修改文件之后的版本报错,也不支持 这个写法了
0 回复 -
landon VIP0
1周前5.1.4.216版本还有这个错么?是后续版本修复吗?
0 回复