Copying data from ClientDataSet to DBXReader
2 - 2Shares
You probably already read my post Copying data from DBXReader to ClientDataSet, now is time to learn how copy data from ClientDataSet to DBXReader using Delphi or C++Builder.
There are many situations where you will need to copy data between ClientDataSet and DBXReader, specially if you are looking to cache data on DataSnap Servers, I’m preparing a new blog post about that and will publish soon.
The DBXDBReaders unit is part of DBX Framework and contain the TDBXDataSetReader class which is a TDBXReader implementation of TDataSet, in other words using this class you will get a DBXReader representation of any DataSet.
You just need to create a instance of TDBXDataSetReader passing the ClientDataSet and the InstanceOwner (true/false). If InstanceOwner is true, the TDataSet instance is freed when the TDBXDataSetReader instance is freed.
Delphi
TDBXDataSetReader.Create(ClientDataSet, False (* InstanceOwner *) )
C++Builder
TDBXDataSetReader->Create(ClientDataSet, False )
TDBXDataSetReader class is compatible with DataSnap 2010 and XE.
2 - 2Shares
Bom dia Andreano!
O TDBXDataSetReader.Create(ClientDataSet, False (* InstanceOwner *) ) é muito bom mas, está sempre retornando nil quando tento utilizá-lo.
No meu caso, o ClientDataSet é temporário, via método CreateDataSet.
Existe alguma coisa a mais para se fazer?
Obrigado.
@Julio,
Não vejo o porque deste erro, está retornando alguma exception?
Nenhuma até sair da aplicação servidor, nenhuma exception Andreano. O código que estou tentando é este:
function TServerModuleEmpresa.GetUserCompanies(idUsuario: Integer; isMaster, isAdmin: Boolean): TDBXReader;
function CreateCDSEmpresas: TClientDataSet;
var
cdsFieldPos: Integer;
cdsTable: TNewTable;
begin
result := TClientDataSet.Create( Self );
{ ... include some fields to result by result.FieldDefs.Add() ... }
result.CreateDataSet;
end;
var
CDSEmpresas: TClientDataSet;
begin
CDSEmpresas := CreateCDSEmpresas;
builder := GetPreparedBuilder;
builder.Open;
while not builder.Dataset.Eof do
begin
CDSEmpresas.Append;
for pos := 0 to builder.Dataset.FieldCount - 1 do
if CDSEmpresas.FindField( builder.Dataset.Fields[pos].FieldName ) nil then
CDSEmpresas.FieldByName( builder.Dataset.Fields[pos].FieldName ).Value := builder.Dataset.Fields[pos].Value;
CDSEmpresas.Post;
builder.Dataset.Next;
end;
{ ** Definindo o retorno do método ** }
result := TDBXDataSetReader.Create( CDSEmpresas, False );
CDSEmpresas.Free;
builder.Destroy( True );
end;
@Julio, você está destruindo o Reader e não pode, o DataSnap irá fazer isso pra você depois que retornar todo o conteúdo para o cliente
Quando você diz que estou destruindo o reader, seria no CDSEmpresas.Free?
Pq já realizei um teste removendo essa linha e mesmo assim, o conteúdo de result é (nil, nil)
A já agradeço a atenção e a ajuda! =)
@Julio, eu não sei o que o método builder.destroy está fazendo, suponho que você esteja destruindo algo que não deveria até que a informação seja enviada, veja os exemplos que disponibilizei de DataSnap
Entendi @Andreano mas não se preocupe…
Quando o código chega nesta linha abaixo, o conteúdo de CDSEmpresas está definido de forma correta…
result := TDBXDataSetReader.Create( CDSEmpresas, False );
A linha builder.destroy é referente a minha classe de consultas ao banco de dados e não possui ligação com o ClientDataSet.
Não sei se ajudaria mas, nesse fórum tenho todo o código do servidor e do cliente para vc entender melhor: http://www.activedelphi.com.br/forum/viewtopic.php?p=366776#366776
Apenas para testes, reduzi toda a implementação do método para oq está abaixo. Mas continua dando o mesmo problema:
function TServerModuleEmpresa.GetUserCompanies(idUsuario: Integer; isMaster, isAdmin: Boolean): TDBXReader;
begin
CDSEmpresas := CreateCDSEmpresas;
// CDSEmpresas é um TClientDataSet com 4 registros...
result := TDBXDataSetReader.Create( CDSEmpresas, False );
end;
result sempre retorna (nil,nil)
Desculpe Andreano.
A solução simplesmente não funciona! Executei um projeto novo com nada além do código para criar o DBXReader e mesmo assim, sempre retorna (nil,nil)
Não sei se existe alguma influência mas, minha versão é a Embarcadero® Delphi® XE Version 15.0.3890.34076.
BOA NOVA!
No novo projeto criado, realizei outro teste e dessa vez funcionou! Houve confusão da minha parte na determinação do CopyReaderToClientDataSet e ToClientDataSet.
O Delphi, porém, sempre exibe o resultado do TDBXDataSetReader.Create como (nil,nil), oq gera alguma confusão na hora de realizar o debug da implementação.
Obrigado pela força.
Solução funcionando!
Boas, Andreano
Acompanho os seus post e relativamente, à conversão DBXReader para ClientDataSet, no delphi XE3 não funciona?!!!!
TDBXDataSetReader.CopyReaderToClientDataSet, metodo não existe!
Pode me ajudar?
Obrigado
Boa noite. Estou fazendo alguns testes utilizado o delphi XE3. Fiz um método que retorna um conjuntos de dados TDBXReader. No lado cliente preciso exibir esses dados num grid. Li que existe um método chamado CopyReaderToDataSet que faz a copia da estrutura/dados para um dataSet, mas não encontrei esse método no delphi XE3. Tenho o Delphi 2010 onde nele aparece. Alguém sabe dizer se ele foi retirado?