TClientDataSet - Comportamento AutoInc indesejado

23/03/2016

3

Bom dia a todos!

Eu tenho uma rotina que faz a cópia de um TDataSet para outro. Cópia da estrutura e dos dados.

Rotina que efetua a clonagem do TField:
fClonarField(Source: TField; //Field fonte 
                               AOwner: TComponent; //DataSet fonte 
                               bCanReadOnly, //permite campos somente Leitura 
                               bCanFieldsAutoInc: Boolean //permite campos AutoInc 
           ): TField; 
  procedure SetProp(Name: string); 
  var V: variant; 
      PropInfo: PPropInfo; 
  begin 
    PropInfo := TypInfo.GetPropInfo(Source, Name); 
    if PropInfo <> nil then 
    begin 
      try 
        V := TypInfo.GetPropValue(Source,Name); 
        if not VarIsNull(V) 
        then TypInfo.SetPropValue(Result,Name,V); 
      except 
      end; 
    end; 
  end; 
begin 
  Result := TFieldClass(Source.ClassType).Create(AOwner); 
  Result.Alignment              := Source.Alignment; 
  if bCanFieldsAutoInc then 
  begin 
    Result.AutoGenerateValue    := Source.AutoGenerateValue; 
    //Result.ProviderFlags        := [pfInUpdate,pfInWhere]; 
  end 
  else 
  begin 
    Result.AutoGenerateValue    := TAutoRefreshFlag(arNone); 
    //Result.ProviderFlags        := Source.ProviderFlags; 
  end; 
  Result.ProviderFlags          := Source.ProviderFlags; 
  Result.CustomConstraint       := Source.CustomConstraint; 
  Result.ConstraintErrorMessage := Source.ConstraintErrorMessage; 
  Result.DefaultExpression      := Source.DefaultExpression; 
  Result.DisplayLabel           := Source.DisplayLabel; 
  Result.DisplayWidth           := Source.DisplayWidth; 
  Result.FieldName              := Source.FieldName; 
  Result.ImportedConstraint     := Source.ImportedConstraint; 
  Result.LookupDataSet          := Source.LookupDataSet; 
  Result.LookupKeyFields        := Source.LookupKeyFields; 
  Result.LookupResultField      := Source.LookupResultField; 
  Result.KeyFields              := Source.KeyFields; 
  Result.LookupCache            := Source.LookupCache; 
  if bCanReadOnly then 
  begin 
    Result.FieldKind            := Source.FieldKind; 
    Result.ReadOnly             := Source.ReadOnly; 
  end 
  else 
  begin 
    Result.FieldKind            := fkData; 
    Result.ReadOnly             := False; 
  end; 
  Result.Required               := Source.Required; 
  Result.Visible                := Source.Visible; 

  SetProp('EditMask'); 
  SetProp('FixedChar'); 
  SetProp('Size'); 
  SetProp('Transliterate'); 
  SetProp('DisplayFormat'); 
  SetProp('EditFormat'); 
  SetProp('Currency'); 
  SetProp('MaxValue'); 
  SetProp('MinValue'); 
  SetProp('Precision'); 
  SetProp('DisplayValues'); 
  SetProp('BlobType'); 
  SetProp('ObjectType'); 
  SetProp('IncludeObjectField'); 
  SetProp('ReferenceTableName'); 
  SetProp('Active'); 
  SetProp('Expression'); 
  SetProp('GroupingLevel'); 
  SetProp('IndexName'); 
end; 

Esta é a minha rotina de clonagem dos campos.
Em uma clonagem específica, chamo esta rotina informando FALSE para os parâmetros booleanos, fazendo com que o TField retornado não seja Auto Incremento nem Somente Leitura.

Esta rotina funcionava antes, mas eu fazia todas os updates via SQL, e agora implementei para fazer as inserções e atualizações com Append na query de consulta das tabelas.

E funciona bem as inserções e updates, porém, como todas as minhas PKs são AutoInc, elas devem ser informadas em TFDQuery.UpdateOptions.AutoIncFields.

Isto afetou minhas clonagem de DataSets. Este bloco:
if bCanFieldsAutoInc then 
  begin 
    Result.AutoGenerateValue    := Source.AutoGenerateValue; 
    //Result.ProviderFlags        := [pfInUpdate,pfInWhere]; 
  end 
  else 
  begin 
    Result.AutoGenerateValue    := TAutoRefreshFlag(arNone); 
    //Result.ProviderFlags        := Source.ProviderFlags; 
  end; 
  Result.ProviderFlags          := Source.ProviderFlags; 

Eu escrevi para resolver, pois informando AutoGenerateValue para arNone o campo deve abandonar seu comportamento AutoInc.

Mas isto não está acontecendo. Ao copiar os dados, o valor PK informado é ignorado, no comando Post, sendo substituído por 1, 2, 3, etc....
Responder