Accesing non dynamic properties in a dynamic way

Hi
In a project I have the need to access some on my entity properties in a dynamic way. This requirement is not because of unkown fields during compile time, but to access known columns in a dynamic way, for example using something like MyEntity.PropByName('name').AsString (similar to FieldByName of TDataset).

For example I have the following column declaration:

    [Column('FIRST_NAME', [], 50)]
    FFirstName: Nullable<string>;

I want to be able access this column like MyObject.PropByName('FIRST_NAME')
My current solution is that I am using TAureliusDataset to access FIRST_NAME.

Can you recommend an alternative approach?

Thanks in advance

To make my question more clear let's say I have the following code:

procedure TUserMessageParserBase.UpdateChatContext(FieldName: string;
  FieldType: TFieldType; Value: Variant);
begin
  var ChatContext := FManager.Find<TChatContext>
    .Add(Dic.ChatContext.BotId.Id = FUserMessageRequest.BotId)
    .Add(Dic.ChatContext.UserPlatformId = FUserMessageRequest.UserPlatformId)
    .Add(Dic.ChatContext.ConversationId = FUserMessageRequest.ConversationId)
    .UniqueResult;
  if ChatContext = nil then
  begin
    ChatContext := TChatContext.Create;
    ChatContext.BotId := FManager.Find<TBotConfig>(FUserMessageRequest.BotId);
    ChatContext.UserPlatformId := FUserMessageRequest.UserPlatformId;
    ChatContext.ConversationId := FUserMessageRequest.ConversationId;
    FManager.Save(ChatContext);
  end;

  //How to remove this code block which currently depends on TAureliusDataset?
  var ChatContextDataset := TAureliusDataset.Create(nil);
  FManager.AddOwnership(ChatContextDataset);
  ChatContextDataset.SetSourceObject(ChatContext);
  ChatContextDataset.Open;
  ChatContextDataset.Edit;
  case FieldType of
    ftString    : ChatContextDataset.FieldByName(FieldName).AsString := VarAsType(Value, varString);
    ftInteger   : ChatContextDataset.FieldByName(FieldName).AsInteger := VarAsType(Value, varInteger);
    ftDateTime,
    ftDate      : ChatContextDataset.FieldByName(FieldName).AsDateTime := VarAsType(Value, varDate);
    ftFloat     : ChatContextDataset.FieldByName(FieldName).AsFloat := VarAsType(Value, varDouble);
  end;
  ChatContextDataset.Post;
  //end block

  FManager.Flush(ChatContext);
end;

Is there a way to achieve same result without a TAureliusDataset?
Thanks

You can simply use Delphi regular RTTI, that's what it was created for: Run-Time Operations on Types - RAD Studio.

Granted, you will have a little more work to handle Aurelius specific types like Nullable<T> and Proxy<T>. In this case you also have the option to use the entity meta information. It's not documented but here is more or less what you can use:

Entity := FManager.Explorer.FindEntityTypeFromClass(ChatContext.ClassType);
Prop := Entity.Properties.FInd('FieldName');
Prop.Columns[0].Wrapper.SetValue(ChatContext, Value);

Thanks,
Does Prop.Columns[0] have a special meaning here? Or should I call Find to correct column?

  var Entity := FManager.Explorer.FindEntityTypeFromClass(ChatContext.ClassType);
  var Prop := Entity.Properties.Find(FieldName);
  var Column := Prop.Columns.Find(FieldName);
  Column.Wrapper.SetDBValue(ChatContext, Value);

I am little confused here as to Find Entity.Properties I need to go with FFirstName than to find Column I need to use "FIRST_NAME".

Sorry it was my mistake this works perfecly fine. No need to Find column.

Prop.Columns[0].Wrapper.SetValue(ChatContext, Value);
1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.