最近在我们的项目中负责开发一个用于三层中数据交换的模块,要求实现以下功能:
1、数据从总部下发到门店(总部数据下发功能)
2、数据从门店上报到总部(总部数据导入功能)
注:此功能主要用于单据上报
3、门店数据更新与同步(门店数据导入功能)
1)、从总部下发的数据包文件中导入数据(无网络环境支持时)
2)、直接连接总部服务器同步数据(有网络环境支持时)
我想这样实现的,大部分的处理都放在应用层来完成,客户端只向应用层发出数据请求。
在COM+中我没有使用TDataSetProvider来向客户端提供数据集,而是在应用层将客户端需要
的数据取出并进行压缩处理后通过接口函数以Variant类型返回给客户端。
在实现过程中,被TMemoryStream类型与Variant类型之间的转换问题卡住了,后来在LiChaoHui大侠的帮助下解决了这个问题,他提供了以下两个函数:
procedure TDataExchangeRDM.VariantToStream (const V: OLEVariant; Stream : TStream);
var
P : Pointer;
begin
Stream.Position := 0;
Stream.Size := VarArrayHighBound (V, 1) - VarArrayLowBound (V, 1) + 1;
P := VarArrayLock (V);
Stream.Write (P^, Stream.Size);
VarArrayUnlock (V);
Stream.Position := 0;
end;
procedure TDataExchangeRDM.StreamToVariant (Stream : TStream; var V: OLEVariant);
var
P : Pointer;
begin
V := VarArrayCreate ([0, Stream.Size - 1], varByte);
P := VarArrayLock (V);
Stream.Position := 0;
Stream.Read (P^, Stream.Size);
VarArrayUnlock (V);
end;
函数是很简单,可我原来就是没想到!主要是对变体类型理解不足。
在数据压缩方面,我使用的是Delphi中自带的ZLib单元,具体代码如下:
function TDataExchangeRDM.GetDataEx(iClientID: Integer;
const SQLText: WideString): OleVariant;
var
adoDataSet: TADODataSet;
dsp: TDataSetProvider;
M: TMemoryStream;
begin
Result := Null;
InitByClient(iClientID);
adoDataSet := TADODataSet.Create(self);
dsp := TDataSetProvider.Create(self);
M := TMemoryStream.Create;
try
adoDataSet.Connection := adoConn;
adoDataSet.CommandTimeout := 600;
adoDataSet.CommandText := SQLText;
dsp.DataSet := adoDataSet;
adoDataSet.Open;
Result := dsp.Data; //取得结果集
if Result = Null then exit;
VariantToStream(Result,M); //转换到流
M.Position := 0;
Compression(M,clFastest); //压缩流
StreamToVariant(M,Result); //转换到变体返回值
finally
dsp.Free;
adoDataSet.Free;
M.Free;
SetAbort;
end;
end;
于2003-07-12晚修改。
继续阅读《从COM+返回压缩后的数据集到客户端》的全文内容...
--------------------------
新闻:
鲍尔默:不解Google为何推出两款操作系统网站导航:
博客园首页 新闻 .NET频道 社区 博问 闪存 找找看