- fix: AsTable SafeThread

This commit is contained in:
2881099 2022-04-09 18:26:11 +08:00
parent 980ee1e893
commit 932b8fde58
3 changed files with 86 additions and 60 deletions

View File

@ -149,20 +149,20 @@ namespace base_entity
BaseEntity.Initialization(fsql, () => _asyncUow.Value); BaseEntity.Initialization(fsql, () => _asyncUow.Value);
#endregion #endregion
var testitems = new[] var testitems = new[]
{ {
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") }, new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },
new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") }, new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") },
new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") }, new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") },
new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") }, new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") },
new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") }, new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") },
new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") }, new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") },
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") }, new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") },
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") } new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") }
}; };
var sqlatb = fsql.Insert(testitems).NoneParameter(); var sqlatb = fsql.Insert(testitems).NoneParameter();
var sqlat = sqlatb.ToSql(); var sqlat = sqlatb.ToSql();
var sqlatr = sqlatb.ExecuteAffrows(); var sqlatr = sqlatb.ExecuteAffrows();
var sqlatc = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1"))); var sqlatc = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1")));
var sqlatca = sqlatc.ToSql(); var sqlatca = sqlatc.ToSql();

View File

@ -51,6 +51,11 @@ namespace FreeSql.DataAnnotations
tb.AsTableColumn = tb.Columns.TryGetValue(atm.Groups[1].Value, out var trycol) ? trycol : tb.AsTableColumn = tb.Columns.TryGetValue(atm.Groups[1].Value, out var trycol) ? trycol :
tb.ColumnsByCs.TryGetValue(atm.Groups[1].Value, out trycol) ? trycol : throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不存在"); tb.ColumnsByCs.TryGetValue(atm.Groups[1].Value, out trycol) ? trycol : throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不存在");
if (tb.AsTableColumn.Attribute.MapType.NullableTypeOrThis() != typeof(DateTime))
{
tb.AsTableColumn = null;
throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不是 DateTime 类型");
}
int.TryParse(atm.Groups[5].Value, out var atm5); int.TryParse(atm.Groups[5].Value, out var atm5);
string atm6 = atm.Groups[6].Value.ToLower(); string atm6 = atm.Groups[6].Value.ToLower();
tb.AsTableImpl = new DateTimeAsTableImpl(Name, DateTime.Parse($"{atm.Groups[2].Value}-{atm.Groups[3].Value}-{atm.Groups[4].Value}"), dt => tb.AsTableImpl = new DateTimeAsTableImpl(Name, DateTime.Parse($"{atm.Groups[2].Value}-{atm.Groups[3].Value}-{atm.Groups[4].Value}"), dt =>
@ -73,13 +78,14 @@ namespace FreeSql.DataAnnotations
/// <summary> /// <summary>
/// 所有分表名 /// 所有分表名
/// </summary> /// </summary>
ICollection<string> AllTables { get; } string[] AllTables { get; }
string GetTableNameByColumnValue(object columnValue, bool autoExpand = false); string GetTableNameByColumnValue(object columnValue, bool autoExpand = false);
ICollection<string> GetTableNamesByColumnValueRange(object columnValue1, object columnValue2); string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2);
ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils); string[] GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils);
} }
class DateTimeAsTableImpl : IAsTable class DateTimeAsTableImpl : IAsTable
{ {
readonly object _lock = new object();
readonly List<string> _allTables = new List<string>(); readonly List<string> _allTables = new List<string>();
readonly List<DateTime> _allTablesTime = new List<DateTime>(); readonly List<DateTime> _allTablesTime = new List<DateTime>();
readonly DateTime _beginTime; readonly DateTime _beginTime;
@ -105,15 +111,18 @@ namespace FreeSql.DataAnnotations
void ExpandTable(DateTime beginTime, DateTime endTime) void ExpandTable(DateTime beginTime, DateTime endTime)
{ {
if (beginTime > endTime) endTime = _nextTimeFunc(beginTime); if (beginTime > endTime) endTime = _nextTimeFunc(beginTime);
while (beginTime <= endTime) lock (_lock)
{ {
var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value); while (beginTime <= endTime)
var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr); {
if (_allTables.Contains(name)) throw new ArgumentException($"tableName{_tableName} 生成了相同的分表名"); var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value);
_allTables.Insert(0, name); var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr);
_allTablesTime.Insert(0, beginTime); if (_allTables.Contains(name)) throw new ArgumentException($"tableName{_tableName} 生成了相同的分表名");
_lastTime = beginTime; _allTables.Insert(0, name);
beginTime = _nextTimeFunc(beginTime); _allTablesTime.Insert(0, beginTime);
_lastTime = beginTime;
beginTime = _nextTimeFunc(beginTime);
}
} }
} }
DateTime ParseColumnValue(object columnValue) DateTime ParseColumnValue(object columnValue)
@ -137,54 +146,62 @@ namespace FreeSql.DataAnnotations
public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false) public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false)
{ {
var dt = ParseColumnValue(columnValue); var dt = ParseColumnValue(columnValue);
if (dt < _allTablesTime.Last()) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \""); if (dt < _beginTime) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \"");
var tmpTime = _nextTimeFunc(_lastTime); var tmpTime = _nextTimeFunc(_lastTime);
if (dt >= tmpTime && autoExpand) if (dt >= tmpTime && autoExpand)
{ {
// 自动建表 // 自动建表
ExpandTable(tmpTime, dt); ExpandTable(tmpTime, dt);
} }
for (var a = 0; a < _allTables.Count; a++) lock (_lock)
if (dt >= _allTablesTime[a]) {
return _allTables[a]; var allTablesCount = _allTablesTime.Count;
for (var a = 0; a < allTablesCount; a++)
if (dt >= _allTablesTime[a])
return _allTables[a];
}
throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 未匹配到分表名"); throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 未匹配到分表名");
} }
public ICollection<string> GetTableNamesByColumnValueRange(object columnValue1, object columnValue2) public string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2)
{ {
var dt1 = ParseColumnValue(columnValue1); var dt1 = ParseColumnValue(columnValue1);
var dt2 = ParseColumnValue(columnValue2); var dt2 = ParseColumnValue(columnValue2);
if (dt1 > dt2) return new string[0]; if (dt1 > dt2) return new string[0];
int dt1idx = 0, dt2idx = 0; lock (_lock)
if (dt1 < _allTablesTime.Last()) dt1idx = _allTablesTime.Count - 1;
else
{ {
for (var a = _allTablesTime.Count - 2; a > -1; a--) int dt1idx = 0, dt2idx = 0;
var allTablesCount = _allTablesTime.Count;
if (dt1 < _beginTime) dt1idx = allTablesCount - 1;
else
{ {
if (dt1 < _allTablesTime[a]) for (var a = allTablesCount - 2; a > -1; a--)
{ {
dt1idx = a + 1; if (dt1 < _allTablesTime[a])
break; {
dt1idx = a + 1;
break;
}
} }
} }
} if (dt2 > _allTablesTime.First()) dt2idx = 0;
if (dt2 > _allTablesTime.First()) dt2idx = 0; else
else
{
for (var a = 0; a < _allTablesTime.Count; a++)
{ {
if (dt2 >= _allTablesTime[a]) for (var a = 0; a < allTablesCount; a++)
{ {
dt2idx = a; if (dt2 >= _allTablesTime[a])
break; {
dt2idx = a;
break;
}
} }
} }
} if (dt2idx == -1) return new string[0];
if (dt2idx == -1) return new string[0];
if (dt1idx == _allTables.Count - 1 && dt2idx == 0) return _allTables; if (dt1idx == allTablesCount - 1 && dt2idx == 0) return _allTables.ToArray();
var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1); var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1).ToArray();
return names; return names;
}
} }
static readonly ConcurrentDictionary<string, Regex[]> _dicRegSqlWhereDateTimes = new ConcurrentDictionary<string, Regex[]>(); static readonly ConcurrentDictionary<string, Regex[]> _dicRegSqlWhereDateTimes = new ConcurrentDictionary<string, Regex[]>();
@ -239,9 +256,9 @@ namespace FreeSql.DataAnnotations
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
/// <exception cref="Exception"></exception> /// <exception cref="Exception"></exception>
public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils) public string[] GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils)
{ {
if (string.IsNullOrWhiteSpace(sqlWhere)) return _allTables; if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables;
var quoteParameterName = commonUtils.QuoteParamterName(""); var quoteParameterName = commonUtils.QuoteParamterName("");
var quoteParameterNameCharArray = quoteParameterName.ToCharArray(); var quoteParameterNameCharArray = quoteParameterName.ToCharArray();
var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name); var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name);
@ -278,9 +295,9 @@ namespace FreeSql.DataAnnotations
if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}"); if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1)); return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1));
} }
return _allTables; return AllTables;
ICollection<string> LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2) string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2)
{ {
switch (opt1) switch (opt1)
{ {
@ -319,9 +336,9 @@ namespace FreeSql.DataAnnotations
} }
break; break;
} }
return _allTables; return AllTables;
} }
ICollection<string> LocalGetTables2(string opt, DateTime val1) string[] LocalGetTables2(string opt, DateTime val1)
{ {
switch (m.Groups[1].Value) switch (m.Groups[1].Value)
{ {
@ -336,10 +353,19 @@ namespace FreeSql.DataAnnotations
case ">=": case ">=":
return GetTableNamesByColumnValueRange(val1, _lastTime); return GetTableNamesByColumnValueRange(val1, _lastTime);
} }
return _allTables; return AllTables;
} }
} }
public ICollection<string> AllTables => _allTables; public string[] AllTables
{
get
{
lock (_lock)
{
return _allTables.ToArray();
}
}
}
} }
} }

View File

@ -469,8 +469,8 @@ namespace FreeSql.Internal.CommonProvider
if (tb.Table.AsTableImpl != null) if (tb.Table.AsTableImpl != null)
{ {
string[] aret = null; string[] aret = null;
if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables.ToArray(); if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables;
else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils).ToArray(); else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils);
if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray(); if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray();
for (var a = 0; a < aret.Length; a++) for (var a = 0; a < aret.Length; a++)