FetchMode

来源:互联网 发布:华裔学中文知乎 编辑:程序博客网 时间:2024/05/29 17:34

本文通过几个列子解释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方法是实参的值。下面我们做一个演示:

 

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

 

fetch01

1-1

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

如果你将SalesTable_1CustTable_1FetchMode参数设置为”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

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

         Select SalesLine

         Join SalesTable where SalesTable.SalesId = salesLine.salesId

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

 

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

同样以图1-2的结果来做讲解,如果将SalesTableCustTableFetchMode属性都设置为”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);

         }

 

如果将SalesTableCustTableFetchMode属性都设置为”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中,如果将SalesLineFetchMode设置为”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;

}

 

如果将SalesLineFetchMode设置为”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小结:

在你确定子数据源和父数据源的关联是11的时候时,根据你的需要决定是否将设置FetchMode11

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

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

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

 

send方法的参数level

 

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

         如图1-1 SalesLine Level值为1 SalesTablelevel值是2 CustTablelevel值是2.

         如图1-2 Salesline level值是1 SalesTablelevel值是2 CustTablelevel值是3.

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

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

原创粉丝点击