Delphi WebService Soap 一次提交多个 ClientDataSet 的简单方法

用 Delphi 做的 WebService 程序,服务器端有一个 SoapDataModule,里面是连接数据库的 DataSet 和 DataSetProvider,客户端的 ClientDataSet.ProviderName 对应的就是服务器端的 DataSetProvider.

简单的情况下,客户端提交对数据的修改,使用 ClientDataSet1.ApplyUpdates(0); 的代码就可以提交。

但是,如果有多个表需要提交,而且多个表需要在一个数据库事务里面提交,也就是其中一个表提交不成功,则数据库事务回滚,则不能用 ClientDataSet1.ApplyUpdates 的方式了。因为调用两次这个方法,服务器端是创建了两次 SoapDataModule 的实例,没法把两次提交放在一个数据库事务里面。

因此,这里就需要额外写一个服务器端的方法,在这个方法里,一次性提交多个来自客户端的数据。对于 ClientDataSet 来说,提交修改的数据,就是提交 ClientDataSet.Delta。这个 Delta 是一个 OleVariant 类型的数据。

一次提交多个,如何把多个打包到一起?一个方法就是利用 Variant 的 Array 也是 Variant 的特性。代码如下:

在客户端:

procedure TForm1.Button4Click(Sender: TObject);
var
  ADeltas: Variant;
  V1, V2: Variant;
begin
  V1 := VarArrayOf([ClientDataSet1.ProviderName, ClientDataSet1.Delta]);
  V2 := VarArrayOf([ClientDataSet2.ProviderName, ClientDataSet2.Delta]);

  ADeltas := VarArrayOf([V1, V2]);

  SoapConnection1.Connected := False;   // SoapConnection1 要用来调用接口方法,必须:1. 先设置 Connected 为 False; 2. 设置其 SOAPServerIID 为接口的 IID,3. Connected设置为 True
  SoapConnection1.SOAPServerIID := '{965990D3-EBF5-E9CB-017E-A9043479592F}';
  SoapConnection1.Connected := True;
  (SoapConnection1.RIO as ItestSoap).SaveDataSet(ADeltas);
end;

在服务器端,对应的接口方法:

procedure TtestSoap.SaveDataSet(ADeltas: Variant);
var
  i, ErrorCount: Integer;
  S: string;
  VDelta: Variant;
  AProvider: TDataSetProvider;
begin
  //测试把几个 ClientDataSet 的 Delta 打包到一起发送到服务器端,一个方法提交。目的是可以集中到一个数据库事务里面;
  //方法是采用 VarArrayOf() 的方法把几个不同的参数打包到一个 var array 里面,在服务器端通过对 var array 进行解析来获得。
  for I := VarArrayLowBound(ADeltas, 1) to VarArrayHighBound(ADeltas, 1) do
  begin
    S := Adeltas[i][0];
    VDelta := ADeltas[i][1];

    AProvider := Self.FindProvider(S);
    if Assigned(AProvider) then
    begin
      AProvider.ApplyUpdates(Vdelta, 0, ErrorCount); //ErrorCount 是提交的错误数字。检查这个数字就可以回滚事务
    end;
  end;
end;

说明一下:

上述方法里面,ADeltas 是一个 Variant 类型的数据,但它实际上是一个 VarArray 类型的数据。因此可以对它做数组的操作;

然后,它的数组元素,当然也是 Variant 类型的数据;而这个 Variant 类型的数据,同样是一个数组,这个数组的第一位(索引编号为 0),是字符串类型的值,代表的是该 ClientDataSet 对应的 DataSetProvider 的 Name;数组的第二位是 Variant 类型的数据,是 ClientDataSet 的 Delta 数据。

备注:上述服务器端方法里面有个函数是通过 DataSetProvider 的名字字符串,搜索对应的 DataSetProvider 对象实例,代码如下:

function TtestSoap.FindProvider(const ProviderName: string): TDataSetProvider;
var
  C: TComponent;
begin
  C := FindComponent(ProviderName);
  if Assigned(C) then
  begin
    if (C is TDataSetProvider) then
    begin
      Result := TDataSetProvider(C);
    end;
  end;
end;

简单说,就是 Variant 数组,可以包含多个数据类型不同的数据,而它本身也是一个 Variant 类型的数据。类似于把多个不同的数据打包到一起,作为一个参数,从客户端传递给服务器端。然后在服务器端可以通过对数组的操作,把多个不同的数据从一个 Variant 类型的数据里面提取出来。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值