首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

1.4.1  使用TSQLDataSet搭配TDataSetProviderTClientDataSet控件

请回到Delphi 2006集成开发环境,打开前面的范例应用程序的主窗体,然后在主窗体中加入控件集Data Access页签中的TDataSetProviderTClientDataSet控件,此时范例主窗体的画面如图1-19所示。

在前一节中已经说明了由dbExpress取得的结果数据集虽然无法修改,但是只要搭配DelphiDataSnap技术就能够允许应用程序变更其中的数据。因此,现在我们要做的就是在范例应用程序中加入DataSnap的功能。

1-19  在范例主窗体中加入TDataSetProvider以及TClientDataSet控件

在加入了TDataSetProvider控件之后,使用对象查看器设定它的DataSet属性值为主窗体中原先的TSQLDataSet控件,如图1-20所示。

1-20  设定TDataSetProvider控件的DataSet属性值

TDataSetProvider控件能够把属于TDataSet类的控件,例如TSQLDataSet请参考图1-14的类架构图),输出给TClientDataSet控件,以便让TClientDataSet控件能够管理输出TDataSet控件之中的结果数据集数据。

接着使用对象查看器设定刚才加入的TClientDataSet控件的ProviderName属性值为主窗体中的TDataSetProvider控件,如图1-21所示。

1-21  设定TClientDataSet控件的ProviderName属性值

现在TClientDataSet控件便可以管理由TDataSetProvider输出的数据,而TDataSetProvider输出的数据就是它连接的TSQLDataSet从后端数据源中取得的结果数据集。

最后把主窗体中的TDataSource控件的DataSet属性值从原先的TSQLDataSet改为刚才加入的TClientDataSet控件,再把TClientDataSet控件的Active属性值设定为True,这样一来,TClientDataSet便从TDataSetProvider取得数据,并且显示在主窗体的数据感知控件之中。

现在执行这个范例应用程序,读者就会看到类似图1-22所示的画面,从图中我们可以看到在使用了TDataSetProviderTClientDataSet之后,范例应用程序便可以使用TDBNavigator任意地移动目前的记录,也不会出现错误了。因此,使用DataSnap技术之后,dbExpress单向Cursor的限制就已经被克服了。

此外,TDBNavigator中的新增、修改和删除按钮似乎也可以工作,而不像图1-12中一样被暂停使用。读者可以先在范例应用程序中试着修改或删除数据,然后点击【】按钮把数据更新回去。这样做似乎是正确的,但是如果读者结束范例应用程序,然后再次执行范例应用程序,会发现原先修改或删除的数据又出现在范例应用程序中,这代表刚才修改和删除的操作并没有真正对数据发生作用,这是为什么呢?

1-22  执行修改过的范例程序

这是因为在使用DataSnap的应用程序中,当应用程序变更数据并且调用TClientDataSetPost方法或是点击TDBNavigator】按钮更新数据时,只是把数据更新回图1-18中由DataSnap管理的缓存内存中,而数据并没有真正更新回后端数据源之中。要真正把变更的数据更新回数据源中,开发人员必须再调用TClientDataSetApplyUpdates方法。

TClientDataSetApplyUpdates方法会把图1-18中由DataSnap管理的缓存内存中所有已经被变更的数据,包含新增、修改和删除的数据,一起更新回后端数据源中。TClientDataSet事实上是借助它连接的TDataSetProvider控件自动产生SQL语句帮助开发人员更新数据的,在稍后的章节中会详细介绍这个流程。下面是ApplyUpdates方法的声明原型:

function ApplyUpdates(MaxErrors: Integer); Integer; virtual;

ApplyUpdates方法接受一个整数类型的参数:MaxErrorsMaxErrors代表当TDataSetProvider自动更新数据时,开发人员所允许发生的错误次数。我们已经说明了当调用ApplyUpdates方法时,DataSnap会将所有在缓存内存中自上次调用ApplyUpdates方法之后到本次调用ApplyUpdates方法之间所有已变更的数据,一起进行更新。因此,这可能会有许多的变更数据,而MaxErrors就代表在更新这些数据时开发人员允许更新数据时发生错误的次数。如果ApplyUpdates在更新数据时发生了超过MaxErrors指定笔数的次数,那么这整个更新的操作便会被恢复。相反,如果发生的次数小于或等于MaxErrors,那么成功更新的数据仍然会被更新回数据源中,至于没有成功更新的数据,则可以让开发人员借助错误事件处理函数来决定如何处理这些失败的数据,我们将在异常处理的章节中详细介绍。如果传入给ApplyUpdates方法的MaxErrors参数是0,代表不允许发生任何的更新错误;如果传入的参数为–1,代表不管发生多少错误都没有关系,可以先把能够成功更新的数据更新回数据源之中。

因此,现在要把范例应用程序变更的数据更新回数据源之中便非常简单了,只需要在范例应用程序中调用TClientDataSetApplyUpdates方法即可。现在请在主窗体中加入一个TButton,设定它的Caption属性值为ApplyUpdate,如图1-23所示。

1-23  在范例主窗体中加入TButton控件

接着在TButtonOnClick事件处理函数中撰写如下的程序代码:

procedure TForm1.Button1Click(Sender: TObject);

begin

  ClientDataSet1.ApplyUpdates(0);

end;

上面的程序代码调用了TClientDataSetApplyUpdates方法,并且传入的参数为0,这代表不允许发生任何的错误。如果在变更数据时发生了任何问题,那么DataSnap便会产生异常,让开发人员得以处理错误状况,在稍后的章节中我们会介绍如何处理DataSnap的异常状况。

请再次执行范例应用程序,试着修改数据,然后点击主窗体中的【ApplyUpdate】按钮,读者便会发现现在的数据真的被更新回后端数据源中了,如图1-24所示。

1-24  范例程序现在可变更数据了

当然,如果读者不希望用户另外点击按钮就能够把数据更新回数据源中,那么读者可以在TClientDataSetAfterPost事件处理函数中直接调用TClientDataSetApplyUpdates方法,如下所示:

procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);

begin

  ClientDataSet1.ApplyUpdates(0);

end;

不过,这样写应用程序会降低一些执行效率,因此,读者可以让TClientDataSet的变更数据在一定的笔数之后再调用ApplyUpdates方法,一次更新所有的数据。这样做比较有效率,我们在稍后的章节中会介绍如何达到这种效果。

从这个范例中读者可以知道,使用dbExpressDataSnap的应用程序似乎比较麻烦,然而事实上并非如此,因为在下一节讨论TSimpleDataSet时读者便会知道我们可以借助TSimpleDataSet简化这些工作。

使用dbExpressDataSnap比传统的开发方式有许多的优点,例如这样做比传统使用BDE的应用程序有更好的执行效率,也可以轻易把应用程序改为分布式的N-Tier应用系统,还可以把应用程序移植到Linux/.NET上。这些好处都是传统的开发方式无法轻易达成的,在读者熟悉了dbExpressDataSnap之后,可能就不再想使用传统的数据库开发方式了

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论