Copying data from ClientDataSet to DBXReader
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.
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?