FormDataSource之间的连接
单个FormDataSource介绍完后,需要关注的是多个FormDataSource之间的连接.
教程中提到的几种连接方式这里就不再赘述了,教程中介绍的蛮详细,从FormDataSource构造Query的方式可以将教程中提到的连接方式分为两类:
一类是Join类型的,比如InnerJoin,OuterJoin等
另一类是动态连接类型的,比如Active,Delayed等
对这两种类型的连接方式处理,AX是完全不同的,先说第一类连接方式,以InnerJoin为例.
其实这两类的区别就在构造FormDataSource的Query的方式上,Join类型的所有的FormDataSource的Table以Join的方式连接起来构造一个Query,所有的FormDataSource的ExcuteQuery方法执行的都是这个Query.
创建一个Form,包含三个FormDataSource:InventTable,InventSum,InventtDim,其中InventSum InnerJoin InventTable,InventDim InnerJoin InventSum.这样按照设想的话,出来的语句应该如下:
SELECT
*
FROM
INVENTTABLE A
INNER
JOIN
INVENTSUM B
ON
A.ITEMID
=
B.ITEMID
INNER
JOIN
INVENTDIM C
ON
B.INVENTDIMID
=
B.INVENTDIMID
还是通过跟踪SQL的方式来追踪AX自己实现的SQL,可以看到如下语句
Database
: Microsoft SQL Server
SQL statement:
SELECT
*
FROM
INVENTTABLE A(NOLOCK) ,INVENTSUM B(NOLOCK) ,INVENTDIM C(NOLOCK)
WHERE
(A.DATAAREAID
=
'
lgt
'
)
AND
((B.DATAAREAID
=
'
lgt
'
)
AND
(A.ITEMID
=
B.ITEMID))
AND
((C.DATAAREAID
=
'
lgt
'
)
AND
(B.INVENTDIMID
=
C.INVENTDIMID))
ORDER
BY
A.DATAAREAID,A.ITEMID
OPTION
(FAST
1
)
[
ID=14, Reused=No
]
Call stack:
\Classes\QueryRun\
next
\Classes\FormDataSource\executeQuery
\Forms\Form3\Data Sources\InventTable\Methods\executeQuery
-
line
3
跟设想的情况是一样的.
我们知道Form的init在执行super()的时候会调用FormDataSource的init方法,那么在Join类型的情况下,调用各个FormDataSource的init方法的顺序是怎样的那?
我找了半天也没有看到相关文档,我试验的结果是创建DataSource的时候,哪个先创建哪个的init方法先被调用,我自己创建了两个Form,各自有两个FormDataSource InventTable和InventSum,设置等都完全一样,但一个先创建InventTable,一个先创建InventSum,结果其中一个先调用InventTable的Init方法,另一个先调用InventSum的Init方法.
接下来的问题是ExcuteQuery方法的执行,ExcuteQuery的第一次执行是有FormRun的Run方法触发的(当然AutoSearch要保留默认值),那么各个FormDataSource的ExcuteQuery执行顺序有没有规律可循?答案跟Init是一样的,哪个DataSource先创建就先调用哪个的ExcuteQuery方法.那么既然在这种情况下只有一个Query,ExcuetQuery执行多次做啥子?
ExcuteQuery虽然被多次执行了,但真正从数据库中取数据只发生在最根结点的数据源的ExcuteQuery方法.这个也可以通过跟踪SQL语句的方式知道.
OK,第一种方式就介绍到这里.
第二种方式相对简单很多,每个FormDataSource都会对应一个Query,在窗体初始化时,会执行主表的ExcuteQuery方法,从表的ExcuteQuery方法是通过调用从表的LinkActive方法调用的,以后每次主表的当前行变化触发Active方法时都会调用从表的LinkActive方法,从而执行从表的ExcuteQuery方法.下面是SalesTable窗体在加载时执行的SQL语句,从中就可以看出其执行过程.
SalesTable:
Database
: Microsoft SQL Server
SQL statement:
SELECT
*
FROM
SALESTABLE A
WHERE
(DATAAREAID
=
?)
ORDER
BY
A.DATAAREAID,A.SALESID
OPTION
(FAST
1
)
[
ID=3, Reused=No
]
Call stack:
\Classes\QueryRun\
next
\Classes\FormDataSource\executeQuery
\Forms\Form5\Data Sources\SalesTable\Methods\executeQuery
-
line
3
SalesLine:
Database
: Microsoft SQL Server
SQL statement:
SELECT
*
FROM
SALESLINE A
WHERE
((DATAAREAID
=
?)
AND
(SALESID
=
?))
ORDER
BY
A.DATAAREAID,A.SALESID,A.LINENUM
OPTION
(FAST
1
)
[
ID=4, Reused=No
]
Call stack:
\Classes\QueryRun\
next
\Classes\FormDataSource\executeQuery
\Forms\Form5\Data Sources\SalesLine\Methods\executeQuery
-
line
5
\Classes\FormDataSource\linkActive
\Forms\Form5\Data Sources\SalesLine\Methods\linkActive
-
line
3