FetchMode的详细解释


本文通过几个列子解释FetchMode的使用,最后解释reportRun.Send()方法的第二个参数level的来源。

 

FetchMode

 

报表的Query的除最上层的DataSource以外所有的DataSource都有一个FetchMode属性,该属性有两个值: “1:n” 和 “1:1”.

 

FetchMode的设置不会影响到查询语句,也就是说,如果你构造了一个Query实现类型于: select SalesLine

         Join salesTable where salesLine.salesId == salesTable.salesId;

那么你将FetchMode设置为”1:n” 或者”1:1”, Query所等价的语句,始终是如上的语句。

 

FetchMode的作用有两点,一是可以影响DataSource的连接方式(影响查询语句),二是可以影响fetch方法在调用send方法是实参的值。下面我们做一个演示:

 

演示1:FetchMode对查询语句的影响

 

fetch01

图1-1

如图1-1,该Query的结构是一个SalesLine连接两个表SalesTable和CustTable, 但这两个子表是在同一个level的(表之间的Relation必须根据实际情况建立)。

如果你将SalesTable_1和CustTable_1的FetchMode参数设置为”1:n”, 实际的查询语句并不是:

Select SalesLine

         Join SalesTable where SalesTable.SalesId = salesLine.salesId

         Join CustTable where CustTable.AccountNum == SalesLine.CustAccount;

而是:

先查询:select salesLine;

再查询:select SalesTable where SalesTable.SalesId == SalesLine.SalesId;

最后: select CustTable where CustTable.AccountNum == SalesLine.CustAccount;

 

当你将FetchMode设置为 “1:1”时,才可以得到这样的查询语句:

         Select SalesLine

         Join SalesTable where SalesTable.SalesId = salesLine.salesId

         Join CustTable where CustTable.AccountNum == SalesLine.CustAccount;

如果你将Query的结构设置成为如图1-2:

fetch02

图1-2

SalesTable和CustTable的FetchMode属性都为”1:n”, 实际的查询语句将同样是:

         Select SalesLine

         Join SalesTable where SalesTable.SalesId = salesLine.salesId

         Join CustTable where CustTable.AccountNum == SalesLine.CustAccount;

 

演示二:对send方法实参的影响

同样以图1-2的结果来做讲解,如果将SalesTable和CustTable的FetchMode属性都设置为”1:1”, 那么在fetch方法中,运行的过程类似于这样:

         While (this.queryRun().next())

{

                   custTable = this.queryRun().get(tablenum(CustTable));

                   this.send(custTable,3,false);//第二个参数将在后面解释

//第三个参数表示是否调用对应的excutesection方法运行,false表示不调用

SalesTable = this.queryRun().get(tablenum(SalesTable));

This.send(salesTable,2,false);

SalesLine = this.queryRun().get(tablenum(SalesLine));

This.send(salesLine,1,true);

         }

 

如果将SalesTable和CustTable的FetchMode属性都设置为”1:n”, 那么在fetch方法中,运行的过程类似于这样:

         While (this.queryRun().next())

{

SalesLine = this.queryRun().get(tablenum(SalesLine));

This.send(salesLine,1,true);

SalesTable = this.queryRun().get(tablenum(SalesTable));

This.send(salesTable,2,true);

custTable = this.queryRun().get(tablenum(CustTable));

                   this.send(custTable,3,true);

         }

         到目前为止,我所展示的代码只是为了告诉你,FetchMode究竟如何影响了fetch方法调用send方法,但系统实际上做到事前不止这些,下面的例子将向你演示系统究竟是如何做到:

fetch03

图1-3

图1-3所示的report中,如果将SalesLine的FetchMode设置为”1:n”,在fetch方法是这样执行的:

Boolean Fetch()

{

         Boolean ret = true;

         QueryRun qr;

         SalesTable salesTable;

         SalesLine salesLine;

;

Qr = new QueryRun(element);

While(qr.next())

{

         If (qr.changed(tablenum(SalesTable)))

{

         salesTable = qr.get(tablenum(SalesTable));

         this.send(salesTable,1,true);

}

If (qr.changed(tablenum(SalesLine)))

{

salesLine = qr.get(tablenum(SalesLine));

this.send(salesLine,2,true);

                   }

}

Return ret;

}

 

如果将SalesLine的FetchMode设置为”1:1”,在fetch方法是这样执行的:

Boolean Fetch()

{

         Boolean ret = true;

         QueryRun qr;

         SalesTable salesTable;

         SalesLine salesLine;

;

Qr = new QueryRun(element);

While(qr.next())

{

         If (qr.changed(tablenum(SalesTable)))

{

         salesTable = qr.get(tablenum(SalesTable));

salesLine = qr.get(tablenum(SalesLine));

this.send(salesLine,2,false);

         this.send(salesTable,1,true);

}

Else if (qr.changed(tablenum(SalesLine)))

                   {

salesLine = qr.get(tablenum(SalesLine));

this.send(salesLine,2,true);

                   }

}

Return ret;

}

系统实际的代码不是这样,但他所实现的结果是相同的。看起来很奇怪,但是系统就是类似与这样做的,所以在你使用FetchMode属性时,考虑一下fetch取数据的方式是否能够满足你的需要。

 

FetchMode小结:

在你确定子数据源和父数据源的关联是1:1的时候时,根据你的需要决定是否将设置FetchMode为1:1。

1.       如果你不打算让子数据源来激活某一个BODY或Section来运行,那么你完全可以将FetchMode设置为1:1,否则请设置为1:n

2.       如果你想让子数据源和父数据源在同一个BODY里显示,那么你也完全可以将FetchMode设置为1:1

3.       如果子数据源和父数据源的关系不是1:1,请你不要将FetchMode设置为1:1,除非那就是你想要的结果。

 

send方法的参数level

 

         当将一个表作为DataSource放入Query中时,每个DataSource都会有一个level,代表该DataSource在整个query中的层次。这个level值是从根DataSource向下,每增加一个层次,就将level值增加1.

         如图1-1, SalesLine 的Level值为1, SalesTable的level值是2, CustTable的level值是2.

         如图1-2, Salesline 的level值是1, SalesTable的level值是2, CustTable的level值是3.

         系统在获取到一个记录时,会根据其对应的DataSource的层次也即level来设置send方法的第二个参数。

         但是,这个参数究竟起什么作用,我不是很明白,根据目前的测试,并没有发现它能够引起本质上的改变。如果谁研究出来了,希望能告诉我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值