标题:Visual FoxPro 9 C/S方面极富人性化的增强
只看楼主
jjjlan
Rank: 1
等 级:新手上路
帖 子:67
专家分:0
注 册:2004-11-24
 问题点数:0 回复次数:0 
Visual FoxPro 9 C/S方面极富人性化的增强

Visual FoxPro 9 C/S方面极富人性化的增强

今年6月,微软公司如期发布了全球Foxer翘首期盼代号为Europa的Visual FoxPro 9beta 版(以下简称VFP9),下文是我学习、探索 VFP9 C/S方面新增功能时的一些心得,供大家一起分享。自从VFP 8 开始,在C/S方面提供了一个CursorAdapter 类, CursorAdapter 是一个基于松散耦合思想设计的对象化的 Cursor 处理模型。对 CursorAdapter 类很多人对其褒贬不一,特别是一些老的Foxer认为做C/S系统用SPT就足够了,何必再增加一个类呢?但我可以这么说,从VFP9 始,几个CursorAdapter新增加的功能,相信足以使那些纯使用SPT 的Foxer 心动不已了。

下面我先谈谈VFP9 在 CursorAdapter 部分的几个增加和增强。

1.属性值可以超过255 个字符

用过CursorAdapter 类的人都知道,VFP8 时其几个属性 SelectCmd、CursorSchema、UpdateNameList、UpdatableFieldList的长度不能超过255个字符,这在VFP8时让人感觉是一件非常滑稽的事情,当后台表的字段数一多,连使用它自身生成器生成的字符串都要报错,不能保存,这点造成CursorAdapter使用起来极为不便,也是全球Foxer要求解决的呼声最多的地方,现在这个问题在VFP9 中终于得到了彻底解决。

2.生成器生成的CursorSchema 不再是按照字母次序来排列了

当我们设计表单上控件时,只要在表单数据环境里放入CursorAdapter,设置 CursorAdapter 的CursorSchema 属性就会可视化的出现一个Cursor, 此时只要拖动相应字段到表单,即可完成一个个控件的设计,这也是CursorAdapter的优点之一,VFP8 时利用生成器生成的CursorSchema 是按照字母次序排列的,这点造成设计时非常的不方便,大家习惯的是自己设计表时的字段次序,现在VFP9 在这方面也做了非常人性化的修改,现在我们可以完全非常舒服的利用其本身的生成器来生成 CursorSchema 供我们设计表单使用。

3.NoData 和 UseCursorSchema 属性

VFP8 时当把CursorAdapter 设计时放到表单的数据环境里,使用CursorFill()里的这两个参数极为不便,现在好了,把这两个属性单独列了出来。

4.TimeStamp 时间戳字段

VFP8 的CursorAdapter 虽然 WhereType 可以等于 4 ,可是其实时间戳字段真正在更新时却过滤掉了,根本不起任何作用。现在VFP9 的CursorAdapter 增加了 TimestampFieldList属性,如果你的后台表里有时间戳的话,只要设置一下这个属性,然后设置WhereType = 4即可。

5.RecordRefresh()

VFP8时CursorAdapter只能用 CursorRefresh() 来刷新前台,可很多时候,我们可能只需要刷新其中一条或者几条记录的数据,可CursorRefresh(),如果前台记录有 1000 条,也要全部重新读一遍,读取完毕以后,记录指针却始终定位在第一条记录,这样既巨大的浪费了网络资源,同时很多情况下还要花费很大的精力重新定位记录指针。

现在 VFP9 增加了这个极富人性化的方法-----RecordRefresh(),能做到任意刷新此Cursor里的任意一条或者连续几条记录,而且当前记录指针保持不变,看到这里相信做过C/S程序的朋友们是不是有一种跃跃欲试的感觉?这个可以期盼已久的功能啊。

RecordRefresh()里有2个参数,RecordRefresh(nRecords,nRecordOffset) 1) nRecords 表示要刷新几条记录 2) nRecordOffset记录偏移量,指是当前记录开始加几条记录

例子1,比如当前记录号是第5条,我要刷新第7、8两条记录,

oCa.RecordRefresh(2,-2)

例子2, 只刷新当前记录,

oCa.RecordRefresh(1)

6.CursorAdapter 的 Auto-Refresh

VFP9提供了记录的Auto-Refresh,其作用、功能、效果和前面介绍的RecordRefresh() 基本相似,有异曲同功之妙用。让我们来看看具体是怎么使用的吧:

InsertCmdRefreshFieldList、InsertCmdRefreshKeyFieldList、InsertCmdRefreshCmd

这三个新增的属性是针对新增记录时使用,一般我们只需要设置InsertCmdRefreshFieldList、InsertCmdRefreshKeyFieldList即可,从字面已经非常好理解需要设置的内容,InsertCmdRefreshKeyFieldList可以和CursorAdapter的KeyFieldList相同。

UpdateCmdRefreshFieldList、UpdateCmdRefreshKeyFieldList、UpdateCmdRefreshCmd

这三个新增的属性是针对修改记录时使用的,一般我们也只需设置UpdateCmdRefreshFieldList和UpdateCmdRefreshKeyFieldList即可。InsertCmdRefreshKeyFieldList完全可以和CursorAdapter的KeyFieldList相同。

让我们设置好这些属性以后看看效果吧,当TableUpdate()提交后台成功以后,记录就自动刷新了,而且当前的记录指针保持不变,这难道不正是我们想要的吗? 请注意,RecordRefresh()和Auto-Refresh 的区别,虽然RecordRefresh() 也能刷新多条指定的记录,可只能是连续的几条记录,而Auto-Refresh却只刷新已修改过的记录。RecordRefresh()刷新的记录可以自己来指定,可Auto-Refresh 刷新的记录却是 CursorAdapter 来控制的。

7.DelayedMemoFetch()

VFP8 的CursorAdapter 里有一个属性:FetchMemo,当设置FetchMemo = .F. 时,本表里的所有Memo 字段都不读取到前台,这样来大大提高了读取数据时的效率,特别是当Memo字段里内容多的时候,可是当我们需要Memo字段里的内容时怎么办呢?这点是我们一直以来不管用远程视图、SPT还是用CursorAdapter做 C/S 程序时的痛苦矛盾之处,现在我们终于在VFP9的CursorAdapter 里找到了完美的解决办法。

先用文字来说明一下 VFP9 的CursorAdapter 的解决方法,当 CursorFill() 时,所有Memo字段的内容全部为空,以提高读取记录时的效率,但当光标移动到这条记录的这个字段时,自动从后台读取这条记录的当前Memo字段的内容到前台,填充进CursorAdapter里,以我实际操作下来的感觉,几乎根本感觉不到这个读取过程,而数据确确实实读到了前台。

整个设置过程如下:

1)oCa.FetchMemo = .F. 2)oCa.FetchMemoDataSourceType = oCa.DataSourceType 3)oCa.FetchMemoDataSource = oCa.DataSource 4)oCa.FetchMemoCmdList 这个是最关键的,也是最麻烦的: oCA.FetchMemoCmdList= "f1 <SELECT f1 FROM testCAMemoFetch WHERE f0=?EVALUATE(this.RefreshAlias +'.f0')>, f2 <SELECT f2 FROM testCAMemoFetch WHERE f0=?EVALUATE(this.RefreshAlias +'.f0')>"

f1,f2这里是Memo字段名简称 f0一般是关键字段名

this.RefreshAlias可以是this.Alias

我翻译一下,就应该比较好理解了,意思如下:” Memo字段名 <select Memo字段名 From 后台表名 where 关键字段名=?前台的Alias名.关键字段内容>,…..”

只要设置好了以上属性,当前台记录移动到Memo字段时 CursorAdapter 会自动调用DelayedMemoFetch(),来读取Memo字段内容。

注意:DelayedMemoFetch是个内置保护方法,在程序里不能直接调用。

RecordRefrsh()、Auto-Refresh和DelayedMemoFetch() 此三项功能是 SPT 无法做到的,合理使用好此三项功能,能极大的提高整个 C/S 系统的效率,降低网络和服务器开销。但使用RecordRefrsh()和Auto-Refresh功能时有点需要特别注意:大家读到这里应该可以看出,其实此三项功能,都是依靠关键字来定位记录的,可当我们用自增量型字段做关键字时,当新增记录时,其值是更新成功以后才能得到,所以当在前台使用RecordRefrsh()和Auto-Refresh时会因无法定位记录而要出错或得不到正确结果。

以上7点是我认为是 VFP9 CursorAdapter 类最具人性化和效率化的方面的功能增强,下面再说说其他几个C/S 方面的功能增强。

1. RecordsFetched 和 FetchIsComplete

以前我们读取大批量记录的时候,如果想要做一个人性化的进度条,是一件非常不容易的事情,一般只能采取异步方式,先读取记录总数,然后用一个循环,

lnResult = SQLEXEC(lnHandle,“SELECT * FROM …. WHERE …”,“Temp”)

DO WHILE lnResult = 0

liResult = CURSORGETPROP("FetchSize")

此处写入进度条代码 ENDDO

这样做,效果是出来了,可是也有缺陷,异步其实变成了同步。现在 VFP9 在CursorGetProp() 里增加了两个参数,RecordsFetch 和 FetchIsComplete,意思和使用方法如下:

RecordsFetched 返回读取远程表过程中目前所传回来的记录数目

例如:lnResult = CURSORGETPROP("RecordsFetched")

FetchIsComplete 表示读取过程是否已经完成 如果已完成 = .T. 例如:llResult = CURSORGETPROP("FetchIsComplete") 有了这两个属性,要做一个进度条就轻而易举了,而且能实现异步功能不丧失的效果。 RecordsFetch 和 FetchIsComplete应该还有其他用处,留待我们一起来慢慢挖掘吧。

2.SQLIDLEDISCONNECT() 这是我认为 VFP9 中极其有意义的 C/S 功能增强。 尤其是对CursorAdapter,当然对SPT和远程视图也同样适用。 SQLIDLEDISCONNECT() 从字面上理解是暂时中断连接。刚开始,我始终未能理解其意思,可当亲手做了实验以后,就不得不惊叹其功能之强大了。 以前在VFP8下我曾仔细做过 CursorAdapter 的断线重连的测试,得出结论,CursorAdapter断线重连以后,当前数据可以向后台更新,但已经无法CursorRefresh()了,只能重新CursorFill()以后才行,但重新CursorFill()以后,前台的Cursor 等于是重新生成了,这对前台如果是用GRID来绑定 Cursor 时尤为不便。 现在终于盼到了----- SQLIDLEDISCONNECT(),当CursorFill()、

CursorRefresh()或者RecordRefresh()以后 SQLIDLEDISCONNECT(lnHandle),此时检查服务器,确实此句柄已经不存在了,和服务器 完全脱离了关系,为了保险起见,把网线拔了,过一段时间再插上,再对CursoraAdapter 进行数据更新,提交后台,然后在前台执行CursorRefresh()或者RecordRefresh(),这个时候检查服务器,连接句柄自动建立成功了,而且数据确实更新成功并重新刷新。 再用SPT 做了测试,同样得到了完美的结果。 综上所述,一旦执行了SQLIDLEDISCONNECT(),这个句柄就处于休眠状态,此时完全和服务器脱离了关系,一旦发生前台向后台请求任何的任务,此时 VFP 将无需任何条件、无需任何人工干预的自动唤醒此连接,且句柄号不变。 此项功能在用户数较多或者网络环境较差的情况下尤其有用,特别是在降低服务器的资源消耗方面有着非常大的作用。

搜索更多相关主题的帖子: FoxPro Visual 极富 人性化 
2005-06-18 08:55



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-21097-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.412596 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved