使用C#与Crystal Report连接Access数据库报错求助
Crystal Reports连接Access数据库抛出DataSourceException的解决方案
问题描述
在Visual Studio中使用C#和Crystal Report开发应用程序,连接Access数据库时出现「CrystalDecisions.CrystalReports.Engine.DataSourceException」异常。尝试过相关示例但无效,需求是仅通过连接字符串调用report.SetDataSource完成数据库连接并在查看器显示数据,不采用OleDbConnection+OleDbDataAdapter的方式。
当前代码
public partial class Form1 : Form { private string pathReport; private const string CONNECTION_STRING = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Xtreme.mdb"; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog1 = new OpenFileDialog { InitialDirectory = @"D:\", Title = "Browse Text Files", CheckFileExists = true, CheckPathExists = true, DefaultExt = "txt", Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*", FilterIndex = 2, RestoreDirectory = true, ReadOnlyChecked = true, ShowReadOnly = true }; if (openFileDialog1.ShowDialog() == DialogResult.OK) { textBox1.Text = openFileDialog1.FileName; pathReport = openFileDialog1.FileName; } } private void btnViewer_Click(object sender, EventArgs e) { try { OleDbConnection oleDbConnection = new OleDbConnection(CONNECTION_STRING); ReportDocument rd = new ReportDocument(); rd.Load(@pathReport); rd.SetDataSource(oleDbConnection); crViewer.ReportSource = rd; crViewer.Refresh(); } catch(Exception ex) { Console.WriteLine("Error click viewer " + ex.Message); } } }
核心问题分析
SetDataSource方法的参数要求是DataSet、DataTable、DataView或IEnumerable类型,直接传入OleDbConnection对象不符合方法要求,这是导致异常的直接原因。
解决方案
方案1:替换报表的数据库连接信息
Crystal Reports会存储报表设计时的数据源配置,运行时可以通过遍历报表表对象,替换为指定的连接信息,无需手动填充数据集:
private void btnViewer_Click(object sender, EventArgs e) { try { ReportDocument rd = new ReportDocument(); rd.Load(pathReport); // 遍历报表中所有表,更新连接信息 foreach (Table table in rd.Database.Tables) { TableLogOnInfo logOnInfo = table.LogOnInfo; ConnectionInfo connectionInfo = new ConnectionInfo(); // 配置连接信息 connectionInfo.ConnectionString = CONNECTION_STRING; connectionInfo.Type = ConnectionInfoType.OLEDB; connectionInfo.UserID = ""; // Access无密码则留空 connectionInfo.Password = ""; logOnInfo.ConnectionInfo = connectionInfo; table.ApplyLogOnInfo(logOnInfo); // 确保表名称匹配 table.Location = table.Name; } crViewer.ReportSource = rd; crViewer.Refresh(); } catch (Exception ex) { Console.WriteLine("Error click viewer " + ex.Message); } }
方案2:匹配驱动与编译平台
- 若使用
.mdb文件(Jet驱动):Jet 4.0驱动无64位版本,需将项目编译平台设置为x86,避免因位数不匹配抛出异常。 - 若使用
.accdb文件:需更换为ACE驱动,连接字符串示例:
同时需安装对应位数的Microsoft Access Database Engine驱动。Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Xtreme.accdb;Persist Security Info=False;
额外检查项
- 确认Access文件路径正确,应用程序对文件所在目录有读取权限。
- 确保Access文件未被其他程序锁定。
内容的提问来源于stack exchange,提问作者Scripta14
相关产品推荐
相关产品推荐

