# -*- 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, "处")