Is it compulsory to add all columns as property when we create a Entity class for a table in DB?

Hi,

I am using TMS Aurelius in XData and FireDAC with Interbase DB.
I have created a Entity Class for a Table Customer. The Table customer have around 40 columns and I want to use just 15 columns which are important and must required for Customers.
So can I used 15 columns in the Customer Entity class instead of the all 40 columns.
Or it is must required to add all the columns of the table in Entity class.

Appreciate all helps.

You can use 15 columns, unless of course some of the missing columns are required. In this case, you would not be able to create new records since you will not be able to provide values to those non-null columns.

Thanks Wagner,
Is there any option to run a query in Entity class which will fetch data from another table or from a different IB Generator which is not linked to Customer.

I'm afraid I didn't understand the question? The entity classes need previous mapping for Aurelius to know how to retrieve them from database.

Sorry, that I could not make it much clear.

For example, I have a table called 'SETTINGS' which contains some global settings data
and I want to get the settings data in Customer Entity class, to generate new Customer number then how to do it.

My question is that can we run a separate query in entity class like following way if not then how to do it?

Following is my Server Module where I am using the Aurelius Connection and FireDAC connection for Interbase DB

Following is API server module class..

type
  TdmAPIServerServermodule = class(TDataModule)
    SparkleHttpSysDispatcher: TSparkleHttpSysDispatcher;
    XDataServer: TXDataServer;
    XDataConnectionPool: TXDataConnectionPool;
    AureliusConnection: TAureliusConnection;
    XDataServerCORS: TSparkleCorsMiddleware;
    XDataServerJWT: TSparkleJwtMiddleware;
    connMain: TFDConnection;
    FDPhysIBDriverLink1: TFDPhysIBDriverLink;
    AureliusManager1: TAureliusManager;
    AureliusModelEvents1: TAureliusModelEvents;
    procedure XDataServerJWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; var Secret: TArray<System.Byte>);
    procedure XDataServerJWTForbidRequest(Sender: TObject; Context: THttpServerContext; var Forbid: Boolean);
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
  end;

Following is my Customer Entity class...

unit CustomerEntityModel;

interface

uses
  SysUtils, StrUtils,
  Generics.Collections,
  Aurelius.Mapping.Attributes,
  Aurelius.Types.Blob,
  Aurelius.Types.DynamicProperties,
  Aurelius.Types.Nullable,
  Aurelius.Types.Proxy,
  Aurelius.Dictionary.Classes,
  Aurelius.Linq, Aurelius.Events.Manager,
  FireDAC.Comp.Client;

type
  {$RTTI EXPLICIT METHODS([vcPrivate..vcPublished])}

  TCUSTREC = class;

  [Entity]
  [Table('CUSTREC')]
  [UniqueKey('CUSTNO')]
  [Id('FCUSTNO', TIdGenerator.None)]
  TCUSTREC = class
     
  private
    [Column('CUSTNO', [TColumnProp.Required], 7)]
    FCUSTNO: string;
	
    [Column('SHORTNAME', [], 35)]
    FSHORTNAME: Nullable<string>;

    [Column('CUSTNAME', [], 35)]
    FCUSTNAME: Nullable<string>;

    [Column('ADDRESS1', [], 30)]
    FADDRESS1: Nullable<string>;

    [OnInserting] procedure OnInserting(Args: TInsertingArgs);

  private
    function GenerateCustno(Ashortname: String): string;

  public
    property CUSTNO: string read FCUSTNO write FCUSTNO;
    property SHORTNAME: Nullable<string> read FSHORTNAME write FSHORTNAME;
    property CUSTNAME: Nullable<string> read FCUSTNAME write FCUSTNAME;
    property ADDRESS1: Nullable<string> read FADDRESS1 write FADDRESS1;
  end;

implementation

{ TCUSTREC }

function TCUSTREC.GenerateCustno(Ashortname: String)(): string;
var 
  mFirstChars, mSecondChars: String;
  i, mNumbPart, mPosn: integer;
  
  qryTmp: TFDQuery;
  
begin
	mPosn := LastDelimiter(' ',Ashortname);
	mFirstChars := copy(Ashortname,1,2);

	if mPosn > 0 then
	 mSecondChars := copy(Ashortname,mPosn + 1,2)
	else
	 mSecondChars := copy(Ashortname,3,2);

	try
	 mNumbPart := 0;

	 qryTmp := TFDQuery.Create(Nil);
	 qryTmp.Connection := dmAPIServerServermodule.connMain;
	 qryTmp.UpdateOptions.ReadOnly := binReadOnly;		
	 with qryTmp do
  	 begin
	  Close;
	  SQL.Text := ' select intvalue from settings where settingname = ' +QuotedStr('CUSTCODENUM');
	  Open();
	  mNumbPart := Fields[0].AsInteger;
	 end;
	finally
	 qryTmp.Free;
	end;

	if mNumbPart = 0 then
	 mNumbPart := 1;

	if mNumbPart < 10 then
	 Result := mFirstChars + mSecondChars + '0' + InttoStr(mNumbPart)
	else
	 Result := mFirstChars + mSecondChars + InttoStr(mNumbPart);
end;

procedure TCUSTREC.OnInserting(Args: TInsertingArgs);
begin
  with TCUSTREC(Args.Entity) do
  begin
    CUSTNO := GenerateCustNo(SHORTNAME);
  end;
end;

initialization
  RegisterEntity(TCUSTREC);

end.

Following is project file,

program testsvc1;

uses
  Vcl.Forms,
  APIServerModule in 'APIServerModule.pas' {dmAPIServerServermodule: TDataModule},
  MainForm in 'MainForm.pas' {frmMain},
  loginService in 'loginService.pas',
  loginServiceImplementation in 'loginServiceImplementation.pas',
  calendarService in 'calendarService.pas',
  calendarServiceImplementation in 'calendarServiceImplementation.pas',
  callService in 'callService.pas',
  callServiceImplementation in 'callServiceImplementation.pas',
  callModel in 'callModel.pas',
  CustomerEntityModel in 'CustomerEntityModel.pas',

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TdmAPIServerServermodule, dmAPIServerServermodule);
  Application.CreateForm(TfrmMain, frmMain);
  Application.Run;
end.

So here, I have declared the function GenerateCustNo which runs a separate query with TFDquery and the connection is from the API Server module FDConenction.

So, is it the correct way what I am doing now? if now then how to do it?

If this is correct way then will the connection pool work for the FDConnection?

It's one valid way.

No, you are getting a connection directly from the data modeler.

You can also use Aurelius itself, the Args parameter provides a Manager property you can cast to TObjectManager and use Aurelius to perform the request, with the currently configured connection.

So the way, I am using the FDConnection to run a query in Customer Entity class will not create any issue in case of multi user scenario as this is XData application which can be used as api service.

Where can I find a full demo for Aurelius connection which uses FireDAC FDConnection for XData service application?

Actually it is a problem as you are reusing the same TFDConnection in multiple threads. You should create (and later destroy) a new TFDConnection component each time you want to use it. That's why we provide the pool.

You can get a connection from the pool and cast it back to a TFDConnection:

https://doc.tmssoftware.com/biz/aurelius/guide/database.html#referencing-original-component

var
  MyConnection: IDBConnection;
  FDConnection: TFDConnection;
{...}
  FDConnection := (MyConnection as IDBConnectionAdapter).AdaptedConnection as TFDConnection;

You have a demo in folder demos\firedac-sql.

Thank you. Wagner

1 Like

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