mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 增加 AsTable 多次,可查询分表后的多个子表记录,以 UNION ALL 形式执行;
This commit is contained in:
		@@ -809,7 +809,14 @@
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ISelect0`2.AsTable(System.Func{System.Type,System.String,System.String})">
 | 
			
		||||
            <summary>
 | 
			
		||||
            设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名;
 | 
			
		||||
            设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; <para></para>
 | 
			
		||||
            设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 <para></para>
 | 
			
		||||
            如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); <para></para>
 | 
			
		||||
            select * from (SELECT a."Id" as1 FROM "table_1" a) ftb <para></para>
 | 
			
		||||
            UNION ALL<para></para>
 | 
			
		||||
            select * from (SELECT a."Id" as1 FROM "table_2" a) ftb <para></para>
 | 
			
		||||
            UNION ALL<para></para>
 | 
			
		||||
            select * from (SELECT a."Id" as1 FROM "table_3" a) ftb
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="tableRule"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,14 @@ namespace FreeSql
 | 
			
		||||
        Task<T1> FirstAsync();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名;
 | 
			
		||||
        /// 设置表名规则,可用于分库/分表,参数1:实体类型;参数2:默认表名;返回值:新表名; <para></para>
 | 
			
		||||
        /// 设置后可查询分表后的多个子表记录,以 UNION ALL 形式执行。 <para></para>
 | 
			
		||||
        /// 如:select.AsTable((type, oldname) => "table_1").AsTable((type, oldname) => "table_2").AsTable((type, oldname) => "table_3").ToSql(a => a.Id); <para></para>
 | 
			
		||||
        /// select * from (SELECT a."Id" as1 FROM "table_1" a) ftb <para></para>
 | 
			
		||||
        /// UNION ALL<para></para>
 | 
			
		||||
        /// select * from (SELECT a."Id" as1 FROM "table_2" a) ftb <para></para>
 | 
			
		||||
        /// UNION ALL<para></para>
 | 
			
		||||
        /// select * from (SELECT a."Id" as1 FROM "table_3" a) ftb
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="tableRule"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
 
 | 
			
		||||
@@ -906,14 +906,16 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            return (map, field.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected string TableRuleInvoke(Type type, string oldname)
 | 
			
		||||
        protected string[] TableRuleInvoke(Type type, string oldname)
 | 
			
		||||
        {
 | 
			
		||||
            for (var a = _tableRules.Count - 1; a >= 0; a--)
 | 
			
		||||
            List<string> newnames = new List<string>();
 | 
			
		||||
            foreach (var tr in _tableRules)
 | 
			
		||||
            {
 | 
			
		||||
                var newname = _tableRules[a]?.Invoke(type, oldname);
 | 
			
		||||
                if (!string.IsNullOrEmpty(newname)) return newname;
 | 
			
		||||
                var newname = tr?.Invoke(type, oldname);
 | 
			
		||||
                if (!string.IsNullOrEmpty(newname)) newnames.Add(newname);
 | 
			
		||||
            }
 | 
			
		||||
            return oldname;
 | 
			
		||||
            if (newnames.Any() == false) return new[] { oldname };
 | 
			
		||||
            return newnames.Distinct().ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TSelect AsTable(Func<Type, string, string> tableRule)
 | 
			
		||||
 
 | 
			
		||||
@@ -363,5 +363,36 @@ namespace FreeSql.Internal
 | 
			
		||||
            }
 | 
			
		||||
            while (initConns.TryTake(out var conn)) pool.Return(conn);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<Dictionary<Type, string>> GetAllTableRule(List<SelectTableInfo> _tables, Func<Type, string, string[]> tableRuleInvoke)
 | 
			
		||||
        {
 | 
			
		||||
            var tableRuleSorted = new List<(Type, string[])>();
 | 
			
		||||
            var tableRuleDict = new Dictionary<Type, bool>();
 | 
			
		||||
            foreach(var tb in _tables)
 | 
			
		||||
            {
 | 
			
		||||
                if (tb.Type == SelectTableInfoType.Parent) continue;
 | 
			
		||||
                if (tableRuleDict.ContainsKey(tb.Table.Type)) continue;
 | 
			
		||||
                var names = tableRuleInvoke(tb.Table.Type, tb.Table.DbName);
 | 
			
		||||
                tableRuleSorted.Add((tb.Table.Type, names));
 | 
			
		||||
                tableRuleDict.Add(tb.Table.Type, true);
 | 
			
		||||
            }
 | 
			
		||||
            var tableRules = new List<Dictionary<Type, string>>();
 | 
			
		||||
            tableRules.Add(tableRuleSorted.Select(a => (a.Item1, a.Item2.First())).ToDictionary(a => a.Item1, a => a.Item2));
 | 
			
		||||
            for (var z = tableRuleSorted.Count - 1; z >=0; z--)
 | 
			
		||||
            {
 | 
			
		||||
                var tbrd = tableRuleSorted[z];
 | 
			
		||||
                var curpos = tableRules.Count;
 | 
			
		||||
                for (var a = 1; a < tbrd.Item2.Length; a++)
 | 
			
		||||
                {
 | 
			
		||||
                    for (var b = 0; b < curpos; b++)
 | 
			
		||||
                    {
 | 
			
		||||
                        var tr = new Dictionary<Type, string>();
 | 
			
		||||
                        foreach (var oldtd in tableRules[b]) tr.Add(oldtd.Key, tbrd.Item1 == oldtd.Key ? tbrd.Item2[a] : oldtd.Value);
 | 
			
		||||
                        tableRules.Add(tr);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return tableRules;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user