Skip to content

Commit 932b8fd

Browse files
committed
- fix: AsTable SafeThread
1 parent 980ee1e commit 932b8fd

File tree

3 files changed

+86
-60
lines changed

3 files changed

+86
-60
lines changed

Examples/base_entity/Program.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,20 @@ static void Main(string[] args)
149149
BaseEntity.Initialization(fsql, () => _asyncUow.Value);
150150
#endregion
151151

152-
var testitems = new[]
153-
{
154-
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },
155-
new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") },
156-
new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") },
157-
new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") },
158-
new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") },
159-
new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") },
160-
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") },
161-
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") }
162-
};
163-
var sqlatb = fsql.Insert(testitems).NoneParameter();
164-
var sqlat = sqlatb.ToSql();
165-
var sqlatr = sqlatb.ExecuteAffrows();
152+
var testitems = new[]
153+
{
154+
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11") },
155+
new AsTableLog{ msg = "msg02", createtime = DateTime.Parse("2022-1-2 14:00:12") },
156+
new AsTableLog{ msg = "msg03", createtime = DateTime.Parse("2022-2-2 15:00:13") },
157+
new AsTableLog{ msg = "msg04", createtime = DateTime.Parse("2022-2-8 15:00:13") },
158+
new AsTableLog{ msg = "msg05", createtime = DateTime.Parse("2022-3-8 15:00:13") },
159+
new AsTableLog{ msg = "msg06", createtime = DateTime.Parse("2022-4-8 15:00:13") },
160+
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-6-8 15:00:13") },
161+
new AsTableLog{ msg = "msg07", createtime = DateTime.Parse("2022-7-1") }
162+
};
163+
var sqlatb = fsql.Insert(testitems).NoneParameter();
164+
var sqlat = sqlatb.ToSql();
165+
var sqlatr = sqlatb.ExecuteAffrows();
166166

167167
var sqlatc = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1")));
168168
var sqlatca = sqlatc.ToSql();

FreeSql/DataAnnotations/TableAttribute.cs

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ internal void ParseAsTable(TableInfo tb)
5151

5252
tb.AsTableColumn = tb.Columns.TryGetValue(atm.Groups[1].Value, out var trycol) ? trycol :
5353
tb.ColumnsByCs.TryGetValue(atm.Groups[1].Value, out trycol) ? trycol : throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不存在");
54+
if (tb.AsTableColumn.Attribute.MapType.NullableTypeOrThis() != typeof(DateTime))
55+
{
56+
tb.AsTableColumn = null;
57+
throw new Exception($"[Table(AsTable = xx)] 设置的属性名 {atm.Groups[1].Value} 不是 DateTime 类型");
58+
}
5459
int.TryParse(atm.Groups[5].Value, out var atm5);
5560
string atm6 = atm.Groups[6].Value.ToLower();
5661
tb.AsTableImpl = new DateTimeAsTableImpl(Name, DateTime.Parse($"{atm.Groups[2].Value}-{atm.Groups[3].Value}-{atm.Groups[4].Value}"), dt =>
@@ -73,13 +78,14 @@ public interface IAsTable
7378
/// <summary>
7479
/// 所有分表名
7580
/// </summary>
76-
ICollection<string> AllTables { get; }
81+
string[] AllTables { get; }
7782
string GetTableNameByColumnValue(object columnValue, bool autoExpand = false);
78-
ICollection<string> GetTableNamesByColumnValueRange(object columnValue1, object columnValue2);
79-
ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils);
83+
string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2);
84+
string[] GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils);
8085
}
8186
class DateTimeAsTableImpl : IAsTable
8287
{
88+
readonly object _lock = new object();
8389
readonly List<string> _allTables = new List<string>();
8490
readonly List<DateTime> _allTablesTime = new List<DateTime>();
8591
readonly DateTime _beginTime;
@@ -105,15 +111,18 @@ public DateTimeAsTableImpl(string tableName, DateTime beginTime, Func<DateTime,
105111
void ExpandTable(DateTime beginTime, DateTime endTime)
106112
{
107113
if (beginTime > endTime) endTime = _nextTimeFunc(beginTime);
108-
while (beginTime <= endTime)
114+
lock (_lock)
109115
{
110-
var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value);
111-
var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr);
112-
if (_allTables.Contains(name)) throw new ArgumentException($"tableName:{_tableName} 生成了相同的分表名");
113-
_allTables.Insert(0, name);
114-
_allTablesTime.Insert(0, beginTime);
115-
_lastTime = beginTime;
116-
beginTime = _nextTimeFunc(beginTime);
116+
while (beginTime <= endTime)
117+
{
118+
var dtstr = beginTime.ToString(_tableNameFormat.Groups[1].Value);
119+
var name = _tableName.Replace(_tableNameFormat.Groups[0].Value, dtstr);
120+
if (_allTables.Contains(name)) throw new ArgumentException($"tableName:{_tableName} 生成了相同的分表名");
121+
_allTables.Insert(0, name);
122+
_allTablesTime.Insert(0, beginTime);
123+
_lastTime = beginTime;
124+
beginTime = _nextTimeFunc(beginTime);
125+
}
117126
}
118127
}
119128
DateTime ParseColumnValue(object columnValue)
@@ -137,54 +146,62 @@ DateTime ParseColumnValue(object columnValue)
137146
public string GetTableNameByColumnValue(object columnValue, bool autoExpand = false)
138147
{
139148
var dt = ParseColumnValue(columnValue);
140-
if (dt < _allTablesTime.Last()) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \"");
149+
if (dt < _beginTime) throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 不能小于 \"{_beginTime.ToString("yyyy-MM-dd HH:mm:ss")} \"");
141150
var tmpTime = _nextTimeFunc(_lastTime);
142151
if (dt >= tmpTime && autoExpand)
143152
{
144153
// 自动建表
145154
ExpandTable(tmpTime, dt);
146155
}
147-
for (var a = 0; a < _allTables.Count; a++)
148-
if (dt >= _allTablesTime[a])
149-
return _allTables[a];
156+
lock (_lock)
157+
{
158+
var allTablesCount = _allTablesTime.Count;
159+
for (var a = 0; a < allTablesCount; a++)
160+
if (dt >= _allTablesTime[a])
161+
return _allTables[a];
162+
}
150163
throw new Exception($"分表字段值 \"{dt.ToString("yyyy-MM-dd HH:mm:ss")}\" 未匹配到分表名");
151164
}
152-
public ICollection<string> GetTableNamesByColumnValueRange(object columnValue1, object columnValue2)
165+
public string[] GetTableNamesByColumnValueRange(object columnValue1, object columnValue2)
153166
{
154167
var dt1 = ParseColumnValue(columnValue1);
155168
var dt2 = ParseColumnValue(columnValue2);
156169
if (dt1 > dt2) return new string[0];
157170

158-
int dt1idx = 0, dt2idx = 0;
159-
if (dt1 < _allTablesTime.Last()) dt1idx = _allTablesTime.Count - 1;
160-
else
171+
lock (_lock)
161172
{
162-
for (var a = _allTablesTime.Count - 2; a > -1; a--)
173+
int dt1idx = 0, dt2idx = 0;
174+
var allTablesCount = _allTablesTime.Count;
175+
if (dt1 < _beginTime) dt1idx = allTablesCount - 1;
176+
else
163177
{
164-
if (dt1 < _allTablesTime[a])
178+
for (var a = allTablesCount - 2; a > -1; a--)
165179
{
166-
dt1idx = a + 1;
167-
break;
180+
if (dt1 < _allTablesTime[a])
181+
{
182+
dt1idx = a + 1;
183+
break;
184+
}
168185
}
169186
}
170-
}
171-
if (dt2 > _allTablesTime.First()) dt2idx = 0;
172-
else
173-
{
174-
for (var a = 0; a < _allTablesTime.Count; a++)
187+
if (dt2 > _allTablesTime.First()) dt2idx = 0;
188+
else
175189
{
176-
if (dt2 >= _allTablesTime[a])
190+
for (var a = 0; a < allTablesCount; a++)
177191
{
178-
dt2idx = a;
179-
break;
192+
if (dt2 >= _allTablesTime[a])
193+
{
194+
dt2idx = a;
195+
break;
196+
}
180197
}
181198
}
182-
}
183-
if (dt2idx == -1) return new string[0];
199+
if (dt2idx == -1) return new string[0];
184200

185-
if (dt1idx == _allTables.Count - 1 && dt2idx == 0) return _allTables;
186-
var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1);
187-
return names;
201+
if (dt1idx == allTablesCount - 1 && dt2idx == 0) return _allTables.ToArray();
202+
var names = _allTables.GetRange(dt2idx, dt1idx - dt2idx + 1).ToArray();
203+
return names;
204+
}
188205
}
189206

190207
static readonly ConcurrentDictionary<string, Regex[]> _dicRegSqlWhereDateTimes = new ConcurrentDictionary<string, Regex[]>();
@@ -239,9 +256,9 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
239256
/// </summary>
240257
/// <returns></returns>
241258
/// <exception cref="Exception"></exception>
242-
public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils)
259+
public string[] GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils)
243260
{
244-
if (string.IsNullOrWhiteSpace(sqlWhere)) return _allTables;
261+
if (string.IsNullOrWhiteSpace(sqlWhere)) return AllTables;
245262
var quoteParameterName = commonUtils.QuoteParamterName("");
246263
var quoteParameterNameCharArray = quoteParameterName.ToCharArray();
247264
var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name);
@@ -278,9 +295,9 @@ public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParam
278295
if (val1 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
279296
return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(val1));
280297
}
281-
return _allTables;
298+
return AllTables;
282299

283-
ICollection<string> LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2)
300+
string[] LocalGetTables(string opt1, string opt2, DateTime val1, DateTime val2)
284301
{
285302
switch (opt1)
286303
{
@@ -319,9 +336,9 @@ ICollection<string> LocalGetTables(string opt1, string opt2, DateTime val1, Date
319336
}
320337
break;
321338
}
322-
return _allTables;
339+
return AllTables;
323340
}
324-
ICollection<string> LocalGetTables2(string opt, DateTime val1)
341+
string[] LocalGetTables2(string opt, DateTime val1)
325342
{
326343
switch (m.Groups[1].Value)
327344
{
@@ -336,10 +353,19 @@ ICollection<string> LocalGetTables2(string opt, DateTime val1)
336353
case ">=":
337354
return GetTableNamesByColumnValueRange(val1, _lastTime);
338355
}
339-
return _allTables;
356+
return AllTables;
340357
}
341358
}
342359

343-
public ICollection<string> AllTables => _allTables;
360+
public string[] AllTables
361+
{
362+
get
363+
{
364+
lock (_lock)
365+
{
366+
return _allTables.ToArray();
367+
}
368+
}
369+
}
344370
}
345371
}

FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,8 @@ string[] LocalGetTableNames(SelectTableInfo tb)
469469
if (tb.Table.AsTableImpl != null)
470470
{
471471
string[] aret = null;
472-
if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables.ToArray();
473-
else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils).ToArray();
472+
if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables;
473+
else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils);
474474
if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray();
475475

476476
for (var a = 0; a < aret.Length; a++)

0 commit comments

Comments
 (0)