Fórum Ajuda com alternativa para substituir DBXReader no Firedac #528318

10/08/2015

0

Olá a todos

Estou migrando meu sistema de DBExpress para Firedac.

Na consulta do banco utilizo DBXReader, e pelo que pesquisei na internet o Firedac não possui nada parecido, com isto venho aqui pedir uma ajuda

Tenho esta rotina que recebe o DBXReader e vai "povoando o objeto" com os campos correspondentes

class function TGenericVO<Tabela>.RetornoDBXReader(pRetorno: TDBXReader): Tabela;
var
  Obj: Tabela;
  Value: TValue;
  I, A: Integer;
  Contexto: TRttiContext;
  Tipo: TRttiType;
  Propriedade: TRttiProperty;
  Propriedades: TArray<TRttiProperty>;
  Atributo: TCustomAttribute;
  NomeCampo: string;
  DBXValueType: TDBXValueType;
  DBXValue: TDBXValue;
  LocalizouPropriedade: Boolean;
begin
  Obj := CreateObject;

  Contexto := TRttiContext.Create;
  try
    Tipo := Contexto.GetType(TObject(Obj).ClassType);

    Propriedades := Tipo.GetProperties;

    for I := 0 to pRetorno.ColumnCount - 1 do
    begin
      DBXValueType := pRetorno.ValueType[I];
      DBXValue := pRetorno.Value[I];
      NomeCampo := UpperCase(DBXValueType.Name);

      with TDBXDataTypes do
      begin
        case DBXValueType.DataType of
          AnsiStringType, WideStringType, BlobType:
            Value := DBXValue.AsString;

          DateType:
            begin
              if DBXValue.AsDate > 0 then
                Value := DBXValue.AsDateTime
              else
                Value := TValue.Empty;
            end;

          DateTimeType, TimeStampType:
            begin
              if DBXValue.AsDateTime > 0 then
                Value := DBXValue.AsDateTime
              else
                Value := TValue.Empty;
            end;

          TimeType:
            begin
              if DBXValue.AsTime > 0 then
                Value := DBXValue.AsTime
              else
                Value := TValue.Empty;
            end;

          Int32Type:
            begin
              if DBXValue.IsNull then
                Value := TValue.Empty
              else
                Value := DBXValue.AsInt32;
            end;

          Int64Type:
            begin
              if DBXValue.IsNull then
                Value := TValue.Empty
              else
                Value := DBXValue.AsInt64;
            end;

          DoubleType, BcdType, CurrencyType:
            begin
              if DBXValue.IsNull then
                Value := TValue.Empty
              else
                Value := DBXValue.AsDouble;
            end;

          BinaryBlobType, BytesType, VariantType:
            Value := TValue.FromVariant(DBXValue.AsVariant);

          BooleanType:
            Value := DBXValue.AsBoolean;

        else
          Value := TValue.Empty;
        end;
      end;

      LocalizouPropriedade := False;
      for A := 0 to Length(Propriedades) - 1 do
      begin
        Propriedade := Propriedades[A];
        for Atributo in Propriedade.GetAttributes do
        begin
          if Atributo is TColumn then
          begin
            if (Atributo as TColumn).Name = NomeCampo then
            begin
              if not Value.IsEmpty then
              begin
                Propriedade.SetValue(TObject(Obj), Value);
              end;

              LocalizouPropriedade := True;
              Break;
            end;
          end
          else if Atributo is TId then
          begin
            if (Atributo as TId).NameField = NomeCampo then
            begin
              if not Value.IsEmpty then
              begin
                Propriedade.SetValue(TObject(Obj), Value);
              end;

              LocalizouPropriedade := True;
              Break;
            end;
          end;
        end;

        if LocalizouPropriedade then
          Break;
      end;
    end;
  finally
    Contexto.Free;
  end;

  Result := Obj;
end;


Pensei em usar FDQuery, mas ai que vem minha falta de experiencia, com FDQuery consigo as informações de Tipo do campo, e nome da Coluna?

Como esta nesta parte:
DBXValueType := pRetorno.ValueType[I];
      DBXValue := pRetorno.Value[I];
      NomeCampo := UpperCase(DBXValueType.Name);


Poderia contornar este problema com o Query ou tem algo melhor???

Obrigado!
Emerson Alexandre

Emerson Alexandre

Responder

Posts

28/08/2015

Cassiano Baltazar.

Estou tentando fazer a mesma migração, mas ainda não consegui.
Responder

Gostei + 0

01/09/2015

Cassiano Baltazar.

Por enquanto resolvi ajustando as rotinas de consulta SQL para utilizar um clientdataset e dele eu extrai o DBXReader.

//Criando query para execução da consulta SQL.
_qryConsulta := TFDQuery.Create(nil);
_qryConsulta.Connection := TConexaoDB.GetInstance(pSessao);
_qryConsulta.sql.Text := ConsultaSQL;

//Crioando DataSetProvider e vinculadndo a query.
_dspConsulta := TDataSetProvider.Create(Application);
_dspConsulta.DataSet := _qryConsulta;

//Criando o ClientDataSet e vinculando ao provider.
_cdsConsulta := TClientDataSet.Create(Application);
_cdsConsulta.SetProvider(_dspConsulta);
_cdsConsulta.Open;

//Extraindo o DBXReder pelo ClientDataSet
result := TDBXDataSetReader.Create(_cdsConsulta, true );

Se alguém souber outra forma mais elegante, posta ai...
Abraços.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar