Farseer

导航

让人费解窗体数据源之间的关系

在Form的数据源之间可以建立各种关系,连接的方式诸如InnerJoin,OuterJoin,Delay之类,可对于两个数据源之间的通过哪些字段进行关联没有显示指定的地方,一直想当然地以为会按照从表上建立的关系去连接,今天让这个问题给郁闷了一把。
问题描述
改造ProdTable窗体,添加SalesLine做为数据源,目的是将销售订单行的信息显示在生产单上。
在ProdTable上添加了一个字段SalesLineRecId,在Form中让ProdTable和SalesLine通过ProdTable的SalesLineRecId和SalesLine的RecId建立InnerJoin关联,但是由于Form的数据源之间没有指定数据源通过哪些字段进行关联的地方,让这个简单而美好的梦想变得曲折离奇。
尝试如下:
1.将数据源SalesLine的AutoQuery设为No,自己动手创建Query,并将SalesLine的JoinSource设为ProdTable,LinkType设为InnerJoin。
由于原ProdTable窗体中已经构造了ProdTable和InventDim关联起来的Query,于是想通过如下方式将自己的数据源SalesLine加到上面去.
重载数据源SalesLine的init方法

public void init()
{
    QueryBuildDataSource qbdsSalesLine;
    ;
    super();

    qbdsSalesLine 
= prodTable_ds.query().dataSourceTable(tableNum(ProdTable)).addDataSource(tableNum(SalesLine));
    qbdsSalesLine.addLink(fieldNum(ProdTable,SalesLineRecId),fieldNum(SalesLine,RecId));

}

按照自己的如意算盘,这样应该就可以work了,谁知世间事不如意十之八九,经过反复尝试,系统自己构造出来的Query好像不能自己再用添加DataSource了,添加Link倒是可以,奇怪得很......
此路不同。。。尝试第二种方式.
2.将数据源SalesLine的AutoQuery设为Yes,并将SalesLine的JoinSource设为ProdTable,LinkType设为InnerJoin,试图通过clearLink去掉原有的连接,然后添加自己的。
至此问题出来了,ProdTable做为主表,SalesLine做为从表,那么两者之间进行关联用哪些字段那?我猜想的话,应该是用在从表SalesLine定义的与ProdTable的关系。


OK,如果不出意外的话,应该用上面的关系进行关联,我们跟踪一下执行的SQL语句(可以用在数据源ProdTable的ExcuteQuery方法中用Info(prodTable_ds.query().dataSourceNo(1).toString())打印出要执行的SQL语句)。

SELECT * FROM ProdTable JOIN * FROM InventDim WHERE ProdTable.InventDimId = InventDim.inventDimId JOIN * FROM SalesLine WHERE ProdTable.ProdId = SalesLine.InventRefId AND ((InventRefType = 3))

从上面的语句可以看出,实际情况是符合猜想的。接下来就是去掉原有连接,添加自己的连接了,重载数据源ProdTable_ds的ExcuteQuery方法。

public void executeQuery()
{
    ;
    prodTable_ds.query().dataSourceTable(tableNum(SalesLine)).clearLinks();
    prodTable_ds.query().dataSourceTable(tablenum(SalesLine)).addLink(fieldNum(ProdTable,SalesLineRecId),fieldNum(SalesLine,RecId));

    info(prodTable_ds.query().dataSourceTable(tableNum(ProdTable)).toString());
    super();
}

如果一切如愿的话,应该就大功告成了,可还是那句话,不如意十之八九......执行的SQL语句如下:

SELECT * FROM ProdTable JOIN * FROM InventDim WHERE ProdTable.InventDimId = InventDim.inventDimId JOIN * FROM SalesLine WHERE ProdTable.SalesLineRecId = SalesLine.RecId AND ((InventRefType = 3))

clearLinks()方法只是把标准连接去掉了,固定字段连接还保留着,这不符合自己最初的梦想。试了半天都不知道如何去掉固定字段连接。只好寻找其他的道路。
感谢Alex Xiong的指教,固定字段连接AX将其处理为Range,所以可以通过ClearRanges或者ClearRange去掉它。
3.将数据源SalesLine的AutoQuery设为Yes,并将ProdTable的JoinSource设为SalesLine,LinkType设为InnerJoin,试图通过clearLink去掉原有的连接,然后添加自己的。
如果按照正常的逻辑,是不需要进行这种尝试的,因为如果按照2的逻辑,这时应该按照从表也就是ProdTable上设定的ProdTable和SalesLine之间的关系进行连接,ProdTable设定的关系如下:

如果按照上述关系进行关联的话,用clearLinks方法去除关系的时候,应该也只能去除标准连接,固定字段连接也没办法去掉,所以也不能达到目的。但是结果依然出乎意料,在这种情况下执行的SQL如下:

SELECT * FROM SalesLine JOIN * FROM ProdTable WHERE SalesLine.InventRefId = ProdTable.ProdId JOIN * FROM InventDim WHERE ProdTable.InventDimId = InventDim.inventDimId

由上可以看出prodTable和SalesLine两个数据源是通过InventRefId和ProdId进行关联的,这两个字段在ProdTable的关系中都没有,至此彻底搞不清楚是按照啥规律进行关联的了。。。。。。
不过由于这时只有一个固定连接,猜想应该可以通过ClearLinks去除掉,然后添加自己的关联字段,尝试重载SalesLine的ExcuteQuery方法:

public void executeQuery()
{
    ;
    salesLine_ds.query().dataSourceTable(tableNum(ProdTable)).clearLinks();
    salesLine_ds.query().dataSourceTable(tableNum(ProdTable)).addLink(fieldNum(SalesLine,recId),fieldNum(ProdTable,SalesLineRecId));

    info(salesLine_ds.query().dataSourceNo(
1).toString());
    super();
}

这时执行的SQL语句如下:

SELECT * FROM SalesLine JOIN * FROM ProdTable WHERE SalesLine.RecId = ProdTable.SalesLineRecId JOIN * FROM InventDim WHERE ProdTable.InventDimId = InventDim.inventDimId
这时从执行的SQL语句看基本上可以实现需求,不过有个现实必须面对,那就是这时的主表是SaleLine,如果一个生产单没有与SalesLine关联就不好意思了,不能显示。
说到这里好像全是没用的,因为没有一个能解决问题。
试图通过自己构造Query来解决这个问题,却发现Query没有办法将两个DataSource关联到同一个DataSource上......

 

posted on 2007-07-20 22:36  佛西亚  阅读(1335)  评论(7编辑  收藏  举报