我能够通过进程内 DataSnap 应用程序访问服务器方法。点击这里了解详情。
但是,进程内数据快照应用程序还有另一个方面。它是 IAppServer 或 TDataSetProvider。
在 Delphi 2009 之前,我使用 TConnectionBroker 和 TLocalConnection 进行进程内数据快照访问。新的 Delphi 2009/2010 DataSnap 允许我们使用 TDSProviderConnection 作为 RemoteServer。但是,我只能使它适用于 TCP/HTTP 连接。我不能将 TDSProviderConnection 用于进程内数据快照应用程序。会提示“无效指针操作”。
这就是我的代码的样子:
var o: TDataModule1;
Q: TSQLConnection;
c: TEmployeeServerClient;
begin
o := TDataModule1.Create(Self);
Q := TSQLConnection.Create(Self);
try
Q.DriverName := 'DSServer1';
Q.LoginPrompt := False;
Q.Open;
DSProviderConnection1.SQLConnection := Q;
DSProviderConnection1.ServerClassName := 'TEmployeeServer';
DSProviderConnection1.Connected := True;
ClientDataSet1.ProviderName := 'DataSetProvider1';
ClientDataSet1.Open;
finally
o.Free;
Q.Free;
end;
end;
TEmployeeServer 是 TDSServerModule 类的后代,由连接在一起的 TDataSetProvider、TSQLDataSet 和 TSQLConnection 组成。
跟踪源码后发现TSQLDataSet确实打开并遍历了数据集。问题的原因应该和下面2个使用TDBXNoOpRow的方法有关
function TDSVoidConnectionHandler.CreateDbxRow: TDBXStreamerRow;
begin
Result := TDBXNoOpRow.Create(DBXContext);
end;
function TDSServerCommand.CreateParameterRow: TDBXRow;
begin
Result := TDBXNoOpRow.Create(FDbxContext);
end;
TDBXNoOpRow 实例将被
procedure TDBXStreamValue.SetRowValue;
begin
if FExtendedType then
begin
if FStreamStreamReader <> nil then
FDbxRow.SetStream(Self, FStreamStreamReader)
else if FByteStreamReader <> nil then
FDbxRow.SetStream(Self, FByteStreamReader)
else
inherited SetRowValue;
end else
inherited SetRowValue;
end;
由于 TDBXNoOpRow 什么都不做,所以数据包没有通过上述方法得到传输。我怀疑这是使用进程内机制出现问题的原因。
我不确定我们是否能够丢弃 TLocalConnection 并用 TDSProviderConnection 代替进程内 DataSnap 应用程序?我已经跟踪 DBX 源代码好几天了,甚至找不到关于这个问题的线索。