Crystal 报告不会显示相关的 table 数据

Crystal Reports won't display related table data

我是 Crystal 报告的新手,正在尝试维护其他人的代码 - 请耐心等待。我有一个 crystal 报告,该报告与具有 2 个相关数据表的数据集相关联。

我按 JurorProfile.JurorPK 分组。在我的组 Header 中,我显示来自 JurorProfile DataTable 的信息。

在报告详细信息中,我有 RowNumber、JurorQuestionAnswers.QuestionJurorQuestionAnswers.Answer

在我的 C# 代码中,我像这样填充数据:


public void SetDataSource(AdoProvider provider, int sessionPK, int jurorPK)
{
   string commandText;
   AdoQuery query;

   commandText = $@"select j.* from Juror j
   where j.JurorPK in (select JurorFK from SessionJurorLink where SessionFK = @sessionId)
   {(jurorPK > 0 ? " and jurorPK = @jurorId" ? "")}
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader jReader = query.ExecuteReader(sessionPK, jurorPK);
   report.Database.Tables["JurorProfile"]
     .SetDataSource((IDataReader)jReader.DataReader);

   commandText = $@"select ... from JurorAnswers ...
   where sessionFK = @sessionId
   {(jurorPK > 0 ? " and jurorFK = @jurorId " : "")}
   order by JurorFK, Rank, ParentFK, QuestionPK
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader qaReader = query.ExecuteReader(sessionPK, jurorPK);
   report.Database.Tables["JurorQuestionAnswers"]
     .SetDataSource((IDataReader)qaReader.DataReader);
}

但是,当我的报告运行时,会显示组标题,并且我会为每个问题打印一个记录编号,但不会显示问题和答案。

看起来,Crystal Reports 没有将我的第二个查询的数据结果映射到 DataTable。

更奇怪的是,JurorQuestionAnswers DataTable 目前有一个多余的姓氏和名字字段。如果我在详细信息区域(JurorQuestionAnswers.LastnameJurorQuestionAnswers.Firstname)中包含这些字段,它们实际上会显示出来——数据已正确映射。

我做错了什么?

更新 - 链接选项卡的图像

当你说 "JurorQuestionAnswers DataTable 当前有一个多余的姓氏和名字字段" 我很想知道当你在数据集中单击它们时是否设计器并查看 Expression 属性,您会看到类似 Parent.Firstname 的内容(或者代码是否包含类似 somedatatable.FirstnameColumn.Expression = "Parent.Firstname" 的内容)。

我已经有很长时间没有使用 CR 了,但我的即时假设是 CR 无法导航 DataRelations,有人解决了这个问题,而是使用 built in ability for a DataColumn Expression to reference other tables 从概念上将 parent 数据导入child table 这样 CR 只有一个 table 的数据要处理。然后 CR 将在 parent 列本身上预先形成一个组(并且因为它们可靠地重复相同的数据,所以它们只分组到一个值)所以你达到相同的效果,你只需要重复数据

如果是这种情况,请遵循模式 - 如果您想要 header 中的 parent 列 X,请将数据列(在设计器中)添加到 child table,称为 ParentX(我喜欢把 Parent 这个词放在由关系派生的列中,这样人们就不会认为它们是多余的,而是会显得迟钝),将其 Experssion 设置为 Parent.X 然后 update/refresh 您的 CR,以便它看到新的列和组

我终于让它工作了。基本上,它涉及用新的数据集替换报表中存在的数据集。

我必须按如下方式更改我的代码:

public void SetDataSource(AdoProvider provider, int sessionPK, int jurorPK)
{
   string commandText;
   AdoQuery query;
   
   // ** Added Direct Reference to DataSet **//
   var ds = new QuestionAnswersData(); 

   commandText = $@"select j.* from Juror j
   where j.JurorPK in (select JurorFK from SessionJurorLink where SessionFK = @sessionId)
   {(jurorPK > 0 ? " and jurorPK = @jurorId" ? "")}
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader jReader = query.ExecuteReader(sessionPK, jurorPK);

   // ** REPLACED THIS LINE **//
   // report.Database.Tables["JurorProfile"]
   //  .SetDataSource((IDataReader)jReader.DataReader); 

   //** WITH THIS LINE **//
   ds.Tables["JurorProfile"].Load((IDataReader)jReader.DataReader, LoadOption.OverwriteChanges, null);  

   commandText = $@"select ... from JurorAnswers ...
   where sessionFK = @sessionId
   {(jurorPK > 0 ? " and jurorFK = @jurorId " : "")}
   order by JurorFK, Rank, ParentFK, QuestionPK
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader qaReader = query.ExecuteReader(sessionPK, jurorPK);

   //** REPLACED THIS LINE **//
   //report.Database.Tables["JurorQuestionAnswers"]
   // .SetDataSource((IDataReader)qaReader.DataReader); 

   //** WITH THIS LINE **//
   ds.Tables["JurorQuestionAnswers"].Load((IDataReader}jReader.DataReader, LoadOption.OverwriteChanges, null);

   //** NOW TIE THE DATASOURCE DIRECTLY TO THE REPORT **//
   base.SetDataSource(ds); 
}