Skip to content

Commit 980ee1e

Browse files
committed
- 完成 [Table(AsTable = xx)] 分表特性查询;
1 parent abaeb7e commit 980ee1e

File tree

20 files changed

+147
-85
lines changed

20 files changed

+147
-85
lines changed

Examples/base_entity/Program.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ static void Main(string[] args)
115115
.UseNoneCommandParameter(true)
116116

117117
.UseConnectionString(FreeSql.DataType.Sqlite, "data source=test1.db;max pool size=5")
118-
.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db")
119-
.UseSlaveWeight(10, 1, 1, 5)
118+
//.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db")
119+
//.UseSlaveWeight(10, 1, 1, 5)
120120

121121

122122
//.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2")
@@ -200,6 +200,26 @@ static void Main(string[] args)
200200
var sqlatd801 = sqlatd8.ToSql();
201201
var sqlatd802 = sqlatd8.ExecuteAffrows();
202202

203+
var sqls1 = fsql.Select<AsTableLog>();
204+
var sqls101 = sqls1.ToSql();
205+
var sqls102 = sqls1.ToList();
206+
207+
var sqls2 = fsql.Select<AsTableLog>().Where(a => a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1")));
208+
var sqls201 = sqls2.ToSql();
209+
var sqls202 = sqls2.ToList();
210+
211+
var sqls3 = fsql.Select<AsTableLog>().Where(a => a.createtime > DateTime.Parse("2022-3-1") && a.createtime < DateTime.Parse("2022-5-1"));
212+
var sqls301 = sqls3.ToSql();
213+
var sqls302 = sqls3.ToList();
214+
215+
var sqls4 = fsql.Select<AsTableLog>().Where(a => a.createtime > DateTime.Parse("2022-3-1"));
216+
var sqls401 = sqls4.ToSql();
217+
var sqls402 = sqls4.ToList();
218+
219+
var sqls5 = fsql.Select<AsTableLog>().Where(a => a.createtime < DateTime.Parse("2022-5-1"));
220+
var sqls501 = sqls5.ToSql();
221+
var sqls502 = sqls5.ToList();
222+
203223
fsql.Aop.AuditValue += new EventHandler<FreeSql.Aop.AuditValueEventArgs>((_, e) =>
204224
{
205225

FreeSql.DbContext/FreeSql.DbContext.xml

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FreeSql/DataAnnotations/TableAttribute.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public interface IAsTable
7676
ICollection<string> AllTables { get; }
7777
string GetTableNameByColumnValue(object columnValue, bool autoExpand = false);
7878
ICollection<string> GetTableNamesByColumnValueRange(object columnValue1, object columnValue2);
79-
ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, TableInfo table, CommonUtils commonUtils);
79+
ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils);
8080
}
8181
class DateTimeAsTableImpl : IAsTable
8282
{
@@ -192,7 +192,7 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
192192
{
193193
return _dicRegSqlWhereDateTimes.GetOrAdd($"{columnName},{quoteParameterName}", cn =>
194194
{
195-
cn = columnName.Replace(@"\[", @"\\[").Replace(@"\]", @"\\]");
195+
cn = columnName.Replace("[", "\\[").Replace("]", "\\]").Replace(".", "\\.");
196196
return new[]
197197
{
198198
new Regex($@"({cn}\s*(<|<=|>|>=|=|between)\s*)(datetime|cdate|to_date)\(('[^']+')\)", RegexOptions.IgnoreCase),
@@ -239,15 +239,22 @@ static Regex[] GetRegSqlWhereDateTimes(string columnName, string quoteParameterN
239239
/// </summary>
240240
/// <returns></returns>
241241
/// <exception cref="Exception"></exception>
242-
public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, TableInfo table, CommonUtils commonUtils)
242+
public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParameter> dbParams, SelectTableInfo tb, CommonUtils commonUtils)
243243
{
244+
if (string.IsNullOrWhiteSpace(sqlWhere)) return _allTables;
244245
var quoteParameterName = commonUtils.QuoteParamterName("");
245246
var quoteParameterNameCharArray = quoteParameterName.ToCharArray();
246-
var regs = GetRegSqlWhereDateTimes(commonUtils.QuoteSqlName(table.AsTableColumn.Attribute.Name), quoteParameterName);
247+
var columnName = commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name);
248+
var regs = GetRegSqlWhereDateTimes($"{(string.IsNullOrWhiteSpace(tb.Alias) ? "" : $"{tb.Alias}.")}{commonUtils.QuoteSqlName(tb.Table.AsTableColumn.Attribute.Name)}", quoteParameterName);
247249
for (var a = 0; a < 16; a++) sqlWhere = regs[a].Replace(sqlWhere, "$1$4");
248250

249251
var m = regs[16].Match(sqlWhere);
250252
if (m.Success) return GetTableNamesByColumnValueRange(m.Groups[1].Value, m.Groups[2].Value);
253+
m = m = regs[18].Match(sqlWhere);
254+
if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value));
255+
m = regs[20].Match(sqlWhere);
256+
if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value));
257+
251258
m = m = regs[17].Match(sqlWhere);
252259
if (m.Success)
253260
{
@@ -256,8 +263,6 @@ public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParam
256263
if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
257264
return GetTableNamesByColumnValueRange(val1, val2);
258265
}
259-
m = m = regs[18].Match(sqlWhere);
260-
if (m.Success) return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(m.Groups[2].Value), ParseColumnValue(m.Groups[4].Value));
261266
m = regs[19].Match(sqlWhere);
262267
if (m.Success)
263268
{
@@ -266,8 +271,6 @@ public ICollection<string> GetTableNamesBySqlWhere(string sqlWhere, List<DbParam
266271
if (val1 == null || val2 == null) throw new Exception($"未能解析分表字段值 {sqlWhere}");
267272
return LocalGetTables(m.Groups[1].Value, m.Groups[3].Value, ParseColumnValue(val1), ParseColumnValue(val2));
268273
}
269-
m = regs[20].Match(sqlWhere);
270-
if (m.Success) return LocalGetTables2(m.Groups[1].Value, ParseColumnValue(m.Groups[2].Value));
271274
m = regs[21].Match(sqlWhere);
272275
if (m.Success)
273276
{

FreeSql/FreeSql.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FreeSql/Internal/CommonExpression.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,7 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
16901690
public abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc);
16911691
public abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc);
16921692
public abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc);
1693+
public string ExpressionConstDateTime(Expression exp) => exp is ConstantExpression operandExpConst ? formatSql(Utils.GetDataReaderValue(typeof(DateTime), operandExpConst.Value), null, null, null) : null;
16931694

16941695
public enum ExpressionStyle
16951696
{

FreeSql/Internal/CommonProvider/DeleteProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public void ToSqlFetch(Action<StringBuilder> fetch)
195195
var sb = new StringBuilder();
196196
if (_table.AsTableImpl != null)
197197
{
198-
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils);
198+
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
199199
foreach (var name in names)
200200
{
201201
_tableRule = old => name;
@@ -228,7 +228,7 @@ async public Task ToSqlFetchAsync(Func<StringBuilder, Task> fetchAsync)
228228
var sb = new StringBuilder();
229229
if (_table.AsTableImpl != null)
230230
{
231-
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils);
231+
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
232232
foreach (var name in names)
233233
{
234234
_tableRule = old => name;

FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,54 @@ public IUpdate<T1> ToUpdate()
460460
protected List<Dictionary<Type, string>> GetTableRuleUnions()
461461
{
462462
var unions = new List<Dictionary<Type, string>>();
463-
var trs = _tableRules.Any() ? _tableRules : new List<Func<Type, string, string>>(new[] { new Func<Type, string, string>((type, oldname) => null) });
463+
var trs = _tableRules.Any() ? _tableRules : new List<Func<Type, string, string>>();
464+
465+
if (trs.Any() == false)
466+
{
467+
string[] LocalGetTableNames(SelectTableInfo tb)
468+
{
469+
if (tb.Table.AsTableImpl != null)
470+
{
471+
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();
474+
if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray();
475+
476+
for (var a = 0; a < aret.Length; a++)
477+
{
478+
if (_orm.CodeFirst.IsSyncStructureToLower) aret[a] = aret[a].ToLower();
479+
if (_orm.CodeFirst.IsSyncStructureToUpper) aret[a] = aret[a].ToUpper();
480+
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, aret[a]);
481+
}
482+
return aret;
483+
}
484+
return new string[] { tb.Table.DbName };
485+
}
486+
var tbnames = _tables.GroupBy(a => a.Table.Type).Select(g => _tables.Where(a => a.Table.Type == g.Key).FirstOrDefault()).Select(a => new { Tb = a, Names = LocalGetTableNames(a) }).ToList();
487+
var dict = new Dictionary<Type, string>();
488+
tbnames.ForEach(a =>
489+
{
490+
dict.Add(a.Tb.Table.Type, a.Names[0]);
491+
});
492+
unions.Add(dict);
493+
for (var a = 0; a < tbnames.Count; a++)
494+
{
495+
if (tbnames[a].Names.Length <= 1) continue;
496+
var unionsCount = unions.Count;
497+
for (var b = 1; b < tbnames[a].Names.Length; b++)
498+
{
499+
for (var d = 0; d < unionsCount; d++)
500+
{
501+
dict = new Dictionary<Type, string>();
502+
foreach (var uit in unions[d])
503+
dict.Add(uit.Key, uit.Key == tbnames[a].Tb.Table.Type ? tbnames[a].Names[b] : uit.Value);
504+
unions.Add(dict);
505+
}
506+
}
507+
}
508+
return unions;
509+
}
510+
if (trs.Any() == false) trs.Add(new Func<Type, string, string>((type, oldname) => null));
464511
foreach (var tr in trs)
465512
{
466513
var dict = new Dictionary<Type, string>();

FreeSql/Internal/CommonProvider/UpdateProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ public void ToSqlFetch(Action<StringBuilder> fetch)
803803
var sb = new StringBuilder();
804804
if (_table.AsTableImpl != null)
805805
{
806-
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils);
806+
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
807807
foreach (var name in names)
808808
{
809809
_tableRule = old => name;
@@ -835,7 +835,7 @@ async public Task ToSqlFetchAsync(Func<StringBuilder, Task> fetchAsync)
835835
var sb = new StringBuilder();
836836
if (_table.AsTableImpl != null)
837837
{
838-
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, _table, _commonUtils);
838+
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
839839
foreach (var name in names)
840840
{
841841
_tableRule = old => name;

Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc)
3434
case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
3535
case "System.Byte": return $"cast({getExp(operandExp)} as Int8)";
3636
case "System.Char": return $"substr(cast({getExp(operandExp)} as String), 1, 1)";
37-
case "System.DateTime": return $"cast({getExp(operandExp)} as DateTime)";
37+
case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as DateTime)";
3838
case "System.Decimal": return $"cast({getExp(operandExp)} as Decimal128(19))";
3939
case "System.Double": return $"cast({getExp(operandExp)} as Float64)";
4040
case "System.Int16": return $"cast({getExp(operandExp)} as Int16)";
@@ -62,7 +62,7 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc)
6262
case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
6363
case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as Int8)";
6464
case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as String), 1, 1)";
65-
case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as DateTime)";
65+
case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as DateTime)";
6666
case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as Decimal128(19))";
6767
case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as Float64)";
6868
case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as Int16)";
@@ -419,10 +419,10 @@ public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression ex
419419
var isLeapYearArgs1 = getExp(exp.Arguments[0]);
420420
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)";
421421

422-
case "Parse": return $"cast({getExp(exp.Arguments[0])} as DateTime)";
422+
case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)";
423423
case "ParseExact":
424424
case "TryParse":
425-
case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as DateTime)";
425+
case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)";
426426
}
427427
}
428428
else
@@ -555,7 +555,7 @@ public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp
555555
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";
556556
case "ToByte": return $"cast({getExp(exp.Arguments[0])} as Int8)";
557557
case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as String), 1, 1)";
558-
case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as DateTime)";
558+
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as DateTime)";
559559
case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as Decimal128(19))";
560560
case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as Float64)";
561561
case "ToInt16":

0 commit comments

Comments
 (0)