- 优化 自动分表 join 分表(自动贴合);

This commit is contained in:
2881099
2023-12-11 23:38:09 +08:00
parent a1b55508a8
commit 7f0bf3cd01
7 changed files with 717 additions and 595 deletions

View File

@ -212,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
foreach (var name in names)
{
_tableRule = old => name;
@ -247,7 +247,7 @@ namespace FreeSql.Internal.CommonProvider
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
foreach (var name in names)
{
_tableRule = old => name;

View File

@ -1,4 +1,5 @@
using FreeSql.Internal.Model;
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using System;
using System.Collections;
using System.Collections.Concurrent;
@ -49,7 +50,8 @@ namespace FreeSql.Internal.CommonProvider
public BaseDiyMemberExpression _diymemexpWithTempQuery;
public Func<DbTransaction> _resolveHookTransaction;
public bool IsDefaultSqlContent => _distinct == false && _is_AsTreeCte == false && _tables.Count == 1 && _where.Length == 0 && _join.Length == 0 &&
public bool IsDefaultSqlContent => _tables.Count == 1 && _tables[0].Table?.AsTableImpl == null &&
_distinct == false && _is_AsTreeCte == false && _where.Length == 0 && _join.Length == 0 &&
string.IsNullOrWhiteSpace(_orderby) && string.IsNullOrWhiteSpace(_groupby) && string.IsNullOrWhiteSpace(_tosqlAppendContent) &&
_aliasRule == null && _selectExpression == null;
@ -868,25 +870,36 @@ namespace FreeSql.Internal.CommonProvider
var unions = new List<Dictionary<Type, string>>();
var trs = _tableRules.Any() ? _tableRules : new List<Func<Type, string, string>>(new[] { new Func<Type, string, string>((type, oldname) => null) });
if (trs.Count == 1 && _tables.Any(a => a.Table != null && a.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trs[0](a.Table.Type, a.Table.DbName)) == true))
if (trs.Count == 1 && _tables.Any(a => a.Table != null && a.Table.AsTableImpl != null &&
string.IsNullOrWhiteSpace(trs[0](a.Table.Type, a.Table.AsTableImpl != null ? null : a.Table.DbName)) == true))
{
string[] LocalGetTableNames(SelectTableInfo tb)
DateTime? DateTimeAsTableImplStart = null, DateTimeAsTableImplEnd = null;
string[] LocalGetTableNames(SelectTableInfo tb)
{
var trname = trs[0](tb.Table.Type, tb.Table.DbName);
var trname = trs[0](tb.Table.Type, tb.Table.AsTableImpl != null ? null : tb.Table.DbName);
if (tb.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trname) == true)
{
string[] aret = null;
if (_where.Length == 0) aret = tb.Table.AsTableImpl.AllTables;
else aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.ToString(), _params, tb, _commonUtils);
if (aret.Any() == false) aret = tb.Table.AsTableImpl.AllTables.Take(1).ToArray();
for (var a = 0; a < aret.Length; a++)
var aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.Length == 0 ? null : _where.ToString(), _params, tb, _commonUtils);
if (aret.Names.Any() == false)
{
if (_orm.CodeFirst.IsSyncStructureToLower) aret[a] = aret[a].ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) aret[a] = aret[a].ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, aret[a]);
var now = DateTime.Now;
aret = new IAsTableTableNameRangeResult(tb.Table.AsTableImpl.AllTables.Take(1).ToArray(), now, now);
}
return aret;
for (var a = 0; a < aret.Names.Length; a++)
{
if (_orm.CodeFirst.IsSyncStructureToLower) aret.Names[a] = aret.Names[a].ToLower();
if (_orm.CodeFirst.IsSyncStructureToUpper) aret.Names[a] = aret.Names[a].ToUpper();
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, aret.Names[a]);
}
if (tb.Table.AsTableImpl is DateTimeAsTableImpl)
{
if (aret.ColumnValue1 is DateTime dt1)
if (DateTimeAsTableImplStart == null || dt1 > DateTimeAsTableImplStart) DateTimeAsTableImplStart = dt1;
if (aret.ColumnValue2 is DateTime dt2)
if (DateTimeAsTableImplEnd == null || dt2 < DateTimeAsTableImplEnd) DateTimeAsTableImplEnd = dt2;
}
return aret.Names;
}
if (string.IsNullOrWhiteSpace(trname) == false)
{
@ -902,13 +915,17 @@ namespace FreeSql.Internal.CommonProvider
}
return new string[] { tb.Table.DbName };
}
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();
var dict = new Dictionary<Type, string>();
var tbnames = _tables.Where(a => a.Type != SelectTableInfoType.Parent).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();
if (DateTimeAsTableImplStart != null && DateTimeAsTableImplEnd != null && tbnames.Where(a => a.Names.Length > 1).Count() > 1)
{
tbnames = tbnames.Select(a => new { a.Tb, Names = a.Tb.Table.AsTableImpl?.GetTableNamesByColumnValueRange(DateTimeAsTableImplStart, DateTimeAsTableImplEnd) ?? a.Names }).ToList();
}
var dict = new Dictionary<Type, string>();
tbnames.ForEach(a =>
{
dict.Add(a.Tb.Table.Type, a.Names[0]);
});
unions.Add(dict);
unions.Add(dict);
for (var a = 0; a < tbnames.Count; a++)
{
if (tbnames[a].Names.Length <= 1) continue;
@ -920,10 +937,34 @@ namespace FreeSql.Internal.CommonProvider
dict = new Dictionary<Type, string>();
foreach (var uit in unions[d])
dict.Add(uit.Key, uit.Key == tbnames[a].Tb.Table.Type ? tbnames[a].Names[b] : uit.Value);
unions.Add(dict);
unions.Add(dict);
}
}
}
if (DateTimeAsTableImplStart != null && DateTimeAsTableImplEnd != null && tbnames.Where(a => a.Names.Length > 1).Count() > 1)
{
for (var uidx = unions.Count - 1; uidx >= 0; uidx--)
{
var ignore = false;
DateTime? dtStart = null, dtEnd = null;
foreach (var ut in unions[uidx])
{
if (tbnames.Where(a => a.Tb.Table.Type == ut.Key).FirstOrDefault()?.Tb.Table?.AsTableImpl is DateTimeAsTableImpl dtImpl == false) continue;
var dtRange = dtImpl.GetRangeByTableName(ut.Value);
if (dtRange == null) continue;
if (dtStart == null) dtStart = dtRange.Item1;
if (dtEnd == null) dtEnd = dtRange.Item2;
if (dtRange.Item1 >= dtEnd || dtRange.Item2 <= dtStart)
{
ignore = true;
break;
}
if (dtRange.Item1 > dtStart) dtStart = dtRange.Item1;
if (dtRange.Item2 < dtEnd) dtEnd = dtRange.Item2;
}
if (ignore) unions.RemoveAt(uidx);
}
}
return unions;
}
if (trs.Any() == false) trs.Add(new Func<Type, string, string>((type, oldname) => null));

View File

@ -971,7 +971,7 @@ namespace FreeSql.Internal.CommonProvider
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
foreach (var name in names)
{
_tableRule = old => name;
@ -1005,7 +1005,7 @@ namespace FreeSql.Internal.CommonProvider
if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils).Names;
foreach (var name in names)
{
_tableRule = old => name;