报表设计器通过ODBC (DSN)连接直接连接到数据库,在设计器中创建水晶报表。同样的报表通过DSN通过Winform(c#)应用程序执行,并提供数据库服务器、数据库、用户ID和密码。
我需要对Crystal Report对象进行这样的更改。ReportDocument不应该通过DSN直接连接到数据库。相反,我们将通过服务调用相应的存储过程和参数作为System.Data.DataTable
来带来数据。这个DataTable
对象应该用来填充/生成报告。
我确实分别从ReportDocument.DataBase.Tables[I].Location
和ReportDocument.DataDefinition
对象中获得了存储过程和参数信息。使用ReportDocument.DataBase.Tables[I].SetDataSource(DataTable)
设置DataSource后,它仍然要求数据库/服务器和用户凭据连接到服务器。
我们可以实现场景和填充报告与内存表,而不是直接连接到数据库通过ODBC?
你需要注意两件事:
- 您正在连接到相同的服务器和数据库名称,用于设计报告
- 您正在连接一个不同的数据库或服务器。
场景1:相同的服务器和数据库名称
在本例中,您需要使用SetDatabaseLogon
方法提供凭据,如下所示
'crDoc1 is your ReportDocument
'dtDataTable is your DataTable
'set database logon info
crDoc1.SetDatabaseLogon("db_user_name", "db_password", "db_server_name_or_ip", "database_name");
'set DataTable as DataSource
crDoc1.SetDataSource(dtDataTable)
场景2:不同的服务器或数据库名称
在这种情况下,您需要使用ApplyLogOnInfo
方法
ConnectionInfo crConInfo = new ConnectionInfo();
TableLogOnInfo crTblLogonInfo = new TableLogOnInfo();
crConInfo.ServerName = "db_server_name_or_ip";
crConInfo.DatabaseName = "database_name";
crConInfo.UserID = "db_user_name";
crConInfo.Password = "db_password";
'crDoc1 is your ReportDocument
'dtDataTable is your DataTable
'Set DataSource to your DataTable
crDoc1.SetDataSource(dtDataTable)
'after setting the DataSource apply Logon credentials to each table in ReportDocument
Tables CrTables = crDoc1.Database.Tables;
foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables) {
crTblLogonInfo = CrTable.LogOnInfo;
crTblLogonInfo.ConnectionInfo = crConInfo;
CrTable.ApplyLogOnInfo(crTblLogonInfo);
}
crDoc1.Refresh();
CrystalReportViewer1.ReportSource = crDoc1;
注意:如果您有任何子报表,您需要分别对所有子报表及其表应用SetDatabaseLogon
和/或ApplyLogOnInfo
。
更新:
将ApplyLogOnInfo应用于子报表
foreach (ReportDocument srSubReport in crDoc1.Subreports) {
foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in srSubReport.Database.Tables) {
crTblLogonInfo = CrTable.LogOnInfo;
crTblLogonInfo.ConnectionInfo = crConInfo;
CrTable.ApplyLogOnInfo(crTblLogonInfo);
}
}