# -*- coding: utf-8 -*- """加载卡顿优化:①计算引擎加公式指纹(PRAGMA user_version 比对,一致跳过重建) ②EnsureFormulaTriggersQuiet 改后台+指纹跳过 ③三表 Reload 加 Stopwatch 耗时日志。幂等。""" import io ROOT = r"C:\Users\099978\Documents\SharpDevelop Projects\成套报价软件\成套报价软件" n = 0 def edit(path, pairs, tag): global n s = io.open(path, encoding="utf-8-sig").read() for old, new in pairs: if old not in s: if new in s: print(tag, "已有(跳过)") continue raise AssertionError(tag + " 锚点缺失: " + old[:70]) s = s.replace(old, new, 1) n += 1 io.open(path, "w", encoding="utf-8-sig").write(s) print(tag, "ok") # 1) 计算引擎:公式指纹 edit(ROOT + r"\计算引擎.cs", [ (''' /// 加载某层级启用中的公式(按排序)。加载失败(表缺/异常)回退默认公式。''', ''' /// 公式表内容指纹(全部公式行串联的稳定 hash)。用于判断触发器是否需要重建。 public static int 公式指纹(System.Data.SQLite.SQLiteConnection fakConn) { try { var sb = new StringBuilder(); using (var cmd = new System.Data.SQLite.SQLiteCommand( "SELECT 层级,目标列,表达式,排序,启用 FROM \\"" + 公式表名 + "\\" ORDER BY 排序;", fakConn)) using (var r = cmd.ExecuteReader()) while (r.Read()) sb.Append(r.GetValue(0)).Append('|').Append(r.GetValue(1)).Append('|') .Append(r.GetValue(2)).Append('|').Append(r.GetValue(3)).Append('|') .Append(r.GetValue(4)).Append(';'); return sb.ToString().GetHashCode(); } catch { return 0; } } /// 读取项目库 user_version(存的是上次重建时的公式指纹)。 public static int 读触发器版本(System.Data.SQLite.SQLiteConnection conn) { using (var cmd = new System.Data.SQLite.SQLiteCommand("PRAGMA user_version;", conn)) return Convert.ToInt32(cmd.ExecuteScalar()); } /// 写入项目库 user_version。 public static void 写触发器版本(System.Data.SQLite.SQLiteConnection conn, int 版本) { using (var cmd = new System.Data.SQLite.SQLiteCommand("PRAGMA user_version=" + 版本 + ";", conn)) cmd.ExecuteNonQuery(); } /// 加载某层级启用中的公式(按排序)。加载失败(表缺/异常)回退默认公式。'''), ], "计算引擎.cs") # 2) 编辑直写库.cs:指纹跳过+后台化 edit(ROOT + r"\编辑直写库.cs", [ (''' /// 进项目/建表/撤销删除后:按公式表重建项目库全部触发器(幂等,安静模式只记日志)。 private void EnsureFormulaTriggersQuiet(string projectId) { try { if (string.IsNullOrWhiteSpace(projectId)) return; string dbPath = GetQuoteDbPath(projectId); if (!System.IO.File.Exists(dbPath)) return; string fak = GetDbFullPath(@"sjk\\fak.db"); using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnStringStatic(dbPath))) using (var fakConn = new System.Data.SQLite.SQLiteConnection(GetConnStringStatic(fak))) { conn.Open(); fakConn.Open(); 计算引擎.EnsureFormulaTable(fakConn); 计算引擎.重建项目全部触发器(conn, null, TuhaoTableName, fakConn); } Log("[公式触发器] 已按公式表重建 [" + projectId + "] 全部触发器"); } catch (Exception ex) { Log("[公式触发器] 重建失败(不影响编辑,但派生列不会自动算): " + ex.Message); } }''', ''' /// 进项目/建表/撤销删除后:按公式表重建项目库全部触发器。 /// ★ 性能:公式指纹与项目库 user_version 一致时直接跳过(毫秒级);需要重建时放后台线程不卡 UI。 private void EnsureFormulaTriggersQuiet(string projectId) { System.Threading.Tasks.Task.Run(delegate { EnsureFormulaTriggersCore(projectId); }); } private void EnsureFormulaTriggersCore(string projectId) { try { if (string.IsNullOrWhiteSpace(projectId)) return; string dbPath = GetQuoteDbPath(projectId); if (!System.IO.File.Exists(dbPath)) return; string fak = GetDbFullPath(@"sjk\\fak.db"); var sw = System.Diagnostics.Stopwatch.StartNew(); using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnStringStatic(dbPath))) using (var fakConn = new System.Data.SQLite.SQLiteConnection(GetConnStringStatic(fak))) { conn.Open(); fakConn.Open(); 计算引擎.EnsureFormulaTable(fakConn); int 指纹 = 计算引擎.公式指纹(fakConn); int 已存 = 计算引擎.读触发器版本(conn); if (指纹 != 0 && 指纹 == 已存) { Log("[公式触发器] 公式未变化,跳过重建 (" + projectId + ")"); return; } 计算引擎.重建项目全部触发器(conn, null, TuhaoTableName, fakConn); 计算引擎.写触发器版本(conn, 指纹); } sw.Stop(); Log("[公式触发器] 已按公式表重建 [" + projectId + "] 全部触发器, 耗时 " + sw.ElapsedMilliseconds + "ms"); } catch (Exception ex) { Log("[公式触发器] 重建失败(不影响编辑,但派生列不会自动算): " + ex.Message); } }'''), ], "编辑直写库.cs") # 3) 三表 Reload 耗时日志 p3 = ROOT + r"\主窗口.cs" edit(p3, [ (''' _tuhaoTable = table; // 记下当前表引用,供关闭/切换时回写 this.advancedDataGridView9.RowCount = table.Rows.Count; this.advancedDataGridView9.Invalidate();''', ''' _tuhaoTable = table; // 记下当前表引用,供关闭/切换时回写 this.advancedDataGridView9.RowCount = table.Rows.Count; this.advancedDataGridView9.Invalidate(); Log("[性能] ReloadTuhaoByProject 耗时 " + _swReload.ElapsedMilliseconds + "ms (含取缓存/查库/转换)");'''), (''' _xianghaoTable = table; // 记下当前表引用,供切换/关闭时回写 this.advancedDataGridView4.RowCount = table.Rows.Count; this.advancedDataGridView4.Invalidate();''', ''' _xianghaoTable = table; // 记下当前表引用,供切换/关闭时回写 this.advancedDataGridView4.RowCount = table.Rows.Count; this.advancedDataGridView4.Invalidate(); Log("[性能] ReloadXianghao 耗时 " + _swReload.ElapsedMilliseconds + "ms (含取缓存/查库/转换)");'''), ], "主窗口.cs") print("合计", n, "处")