C#桌面应用中Crystal Report的Unit Price显示与更新数据不匹配
C# 桌面程序 Crystal Report 不显示SQLite更新后Unit Price值排查方案
以下是按出现概率从高到低排序的排查点,逐个核对即可定位问题:
- 报表未在运行时重载数据库连接,读取了设计时缓存的旧数据
Crystal Reports 设计时拖入字段时,会自动将当时拉取的测试数据内嵌到rpt文件中,如果代码里复用了全局静态的ReportDocument实例,或者没有给报表显式传入最新的数据库连接配置,报表会直接读取内嵌缓存,不会主动连库拉新数据。
每次生成报表时重新实例化报表对象、强制覆写连接配置即可,参考实现:// 禁止复用全局缓存的ReportDocument实例,每次生成都新建 ReportDocument priceReport = new ReportDocument(); // 加载报表文件时用绝对路径,避免相对路径定位错误 string reportPath = Path.Combine(Application.StartupPath, "Reports", "UnitPriceReport.rpt"); priceReport.Load(reportPath); // 配置SQLite连接,注意路径要指向程序实际运行使用的db文件 ConnectionInfo sqliteConn = new ConnectionInfo(); sqliteConn.ServerName = Path.Combine(Application.StartupPath, "Data", "business.db"); sqliteConn.UserID = ""; sqliteConn.Password = ""; sqliteConn.DatabaseName = ""; // 给报表内所有表应用新的连接配置 foreach (Table tbl in priceReport.Database.Tables) { TableLogOnInfo logInfo = tbl.LogOnInfo; logInfo.ConnectionInfo = sqliteConn; tbl.ApplyLogOnInfo(logInfo); } // 强制刷新报表,清除视图缓存 priceReport.Refresh(); crystalReportViewer1.ReportSource = priceReport; - SQLite数据库路径配置错误,程序读取的是被VS覆盖的旧副本
这是SQLite桌面应用的高频坑:如果项目中的db文件被设置为「始终复制」或「如果较新则复制」,每次编译运行时VS都会把项目目录下的初始db文件覆盖到exe输出目录,你手动更新的可能是项目目录下的db,程序实际读取的是输出目录里被还原的旧库。
排查方式:更新完Unit Price数据后,直接到exe所在的运行目录下找到对应db文件,用SQLite可视化工具打开核对字段值,如果值是旧的,修正db文件的复制属性为「不复制」,手动把db放到输出目录,或者统一用固定的公共路径存放db文件即可。 - 报表数据源使用了内存缓存的旧DataSet/DataTable
如果是通过代码填充DataSet后作为数据源传给报表,要确认每次填充前清空了旧表数据,且是在数据库更新操作完成后才执行SQL查询、填充DataTable,不要把提前缓存的全局DataTable直接传给报表。 - 报表开启了「保存数据与报表」选项,字段绑定错误
打开rpt设计文件,在报表选项里找到「保存数据与报表」的勾选框,取消勾选——该选项开启时报表会永久保存第一次加载的数据集,不会主动拉取新数据。同时核对Unit Price字段的绑定来源,确认没有误绑到设计时加的固定值公式、旧参数字段,而是实际映射到数据库的Unit Price列。
快速定位技巧:在给报表设置数据源之前,先执行查询把对应商品的Unit Price值打印到调试输出窗口,确认程序代码读到的数据库值是最新的,再排查报表绑定环节的问题,能快速缩小排查范围。
内容的提问来源于stack exchange,提问作者Shah Faisal
相关产品推荐
相关产品推荐

