目前我已经厌倦了尝试在 Crystal Reports 中解决这个问题。我们有 3 个环境,开发、生产(共享)和本地计算机中的部署。如果我与开发中的生产环境不完全匹配,Crystal Reports 永远不会显示报告。我通过所有论坛进行了大量研究,并尝试了每一个解决方案。我尝试什么都没关系,当我尝试应用新的登录信息时它永远不会起作用,当我循环表以测试连接时它最终会失败:
foreach (CrystalDecisions.CrystalReports.Engine.Table table in document.Database.Tables)
{
TableLogOnInfo tableLogOnInfo = table.LogOnInfo;
tableLogOnInfo.ConnectionInfo = info.ConnectionInfo;
table.ApplyLogOnInfo(tableLogOnInfo);
if (!table.TestConnectivity())
{
string msg = ("Failed to apply log in info for Crystal Report");
throw new ApplicationException(msg);
}
}
如果我将用户或密码更改为无效用户或密码,则之前在 SetConnection 或 SetDatabaseLogon 中会失败。我知道存在无法从集成安全性更改为非集成安全性的错误,因此我将自己的数据库设置为使用常规用户和密码凭据。
我可以清楚地看到未设置连接,因为在我的开发计算机中我设置了无效密码,它失败了,但如果我继续,我会看到报告。在生产计算机中,它总是失败并且也不显示报告(出于调试目的跳过错误)。所以似乎连接是硬编码的,无法更改。
有任何想法吗?我可以发布所有代码来更改连接信息,但我认为这不值得,这是众所周知的。
解决方案
就像许多人告诉我的那样,没有单一的解决方案。似乎取决于 Crystal Reports 版本,它的工作方式有所不同。在我的情况下,以下解决方案适用于 Crystal Reports 10.5.3700。
public static void CrystalReportLogOn(ReportDocument reportParameters, string serverName, string databaseName, string userName, string password)
{
TableLogOnInfo logOnInfo;
ReportDocument subRd;
Sections sects;
ReportObjects ros;
SubreportObject sro;
if (reportParameters == null)
{
throw new ArgumentNullException("reportParameters");
}
try
{
foreach (CrystalDecisions.CrystalReports.Engine.Table t in reportParameters.Database.Tables)
{
logOnInfo = t.LogOnInfo;
logOnInfo.ReportName = reportParameters.Name;
logOnInfo.ConnectionInfo.ServerName = serverName;
logOnInfo.ConnectionInfo.DatabaseName = databaseName;
logOnInfo.ConnectionInfo.UserID = userName;
logOnInfo.ConnectionInfo.Password = password;
logOnInfo.TableName = t.Name;
t.ApplyLogOnInfo(logOnInfo);
t.Location = t.Name;
}
}
catch
{
throw;
}
sects = reportParameters.ReportDefinition.Sections;
foreach (Section sect in sects)
{
ros = sect.ReportObjects;
foreach (ReportObject ro in ros)
{
if (ro.Kind == ReportObjectKind.SubreportObject)
{
sro = (SubreportObject)ro;
subRd = sro.OpenSubreport(sro.SubreportName);
try
{
foreach (CrystalDecisions.CrystalReports.Engine.Table t in subRd.Database.Tables)
{
logOnInfo = t.LogOnInfo;
logOnInfo.ReportName = reportParameters.Name;
logOnInfo.ConnectionInfo.ServerName = serverName;
logOnInfo.ConnectionInfo.DatabaseName = databaseName;
logOnInfo.ConnectionInfo.UserID = userName;
logOnInfo.ConnectionInfo.Password = password;
logOnInfo.TableName = t.Name;
t.ApplyLogOnInfo(logOnInfo);
}
}
catch
{
throw;
}
}
}
}
}
我尝试过的所有其他解决方案都不起作用。