在将DataTable设置为DataSource时报告要求数据库登录

报表设计器在设计器中创建水晶报表,使用ODBC(DSN)连接直接连接到数据库。 通过DSN通过Winform(C#)应用程序执行相同的报告,并提供数据库服务器,数据库,用户ID和密码。

我需要对Crystal Report对象进行此类更改。 ReportDocument不应该通过DSN直接连接到数据库。 相反,我们将通过调用相应的存储过程和参数作为System.Data.DataTable来通过服务提供数据。 此DataTable对象应用于填充/生成报告。

我分别从ReportDocument.DataBase.Tables[I].LocationReportDocument.DataDefinition对象中获取存储过程和参数信息。 在使用ReportDocument.DataBase.Tables[I].SetDataSource(DataTable)设置DataSource之后,它仍然要求数据库/服务器和用户凭据连接到服务器。

我们是否可以实现场景并使用内存表填充报表,而不是通过ODBC直接连接到数据库?

您需要关注的两件事:

  1. 您正在连接到用于设计报告的相同服务器和数据库名称
  2. 您正在连接到其他数据库或服务器

场景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:不同的服务器OR数据库名称

在这种情况下,您需要使用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); } }