Generate entity model¶
Trysil > Generate entity model writes a Delphi unit for each entity of the model and adds it to the active project.
The dialog¶

| Field | Meaning |
|---|---|
| Model directory | Folder of the units, relative to the project folder. Default Model |
| Unit filenames | Pattern of the unit names. Default {ProjectName}.Model.{EntityName} |
| Entities | The entities to generate, all ticked by default. Right click for Select all entities / Unselect all entities |
| Generate filter properties companion | Adds a T<Entity>Properties record to each unit |
| Generate & register API REST controllers | Only for projects created by the API REST wizard |
The unit name pattern accepts two placeholders, ignoring case: {ProjectName}, the name of the .dproj without extension, and {EntityName}. For the project OrdersAPI and the entity Order the default gives OrdersAPI.Model.Order. Nested folders are allowed in Model directory, for example Source/Model, and are created when missing.
The defaults come from Settings. What you choose here is remembered for the project in __trysil\__settings\settings.json.
If a unit with the same name is already in the project, the Expert lists the units that would be overwritten and asks before continuing.
What is generated¶
Each unit contains the entity class with its Trysil attributes, and the getters and setters of the lazy properties. The units are opened in the editor and added to the project: save them as you would any new unit.
For an Order entity with an order date, a customer and a note:
unit OrdersAPI.Model.Order;
{$WARN UNKNOWN_CUSTOM_ATTRIBUTE ERROR}
interface
uses
System.Classes,
System.SysUtils,
Trysil.Types,
Trysil.Attributes,
Trysil.Filter.Expression,
Trysil.Validation.Attributes,
Trysil.Lazy,
OrdersAPI.Model.Customer;
type
{ TOrder }
[TTable('Orders')]
[TSequence('OrdersID')]
TOrder = class
strict private
[TPrimaryKey]
[TColumn('ID')]
FID: TTPrimaryKey;
[TRequired]
[TColumn('OrderDate')]
FOrderDate: TDateTime;
[TRequired]
[TColumn('CustomerID')]
FCustomer: TTLazy<TCustomer>;
[TMaxLength(200)]
[TColumn('Notes')]
FNotes: String;
[TVersionColumn]
[TColumn('VersionID')]
FVersionID: TTVersion;
function GetCustomer: TCustomer;
procedure SetCustomer(const AValue: TCustomer);
public
property ID: TTPrimaryKey read FID;
property OrderDate: TDateTime read FOrderDate write FOrderDate;
property Customer: TCustomer read GetCustomer write SetCustomer;
property Notes: String read FNotes write FNotes;
property VersionID: TTVersion read FVersionID;
end;
ID and VersionID are read-only: Trysil assigns them. The units of the referenced entities are added to the uses clause.
{$WARN UNKNOWN_CUSTOM_ATTRIBUTE ERROR} turns a misspelled attribute into a compile error instead of an attribute silently ignored.
Filter properties companion¶
With Generate filter properties companion ticked, each unit also declares a record with one TTProperty per data column, the primary key included and the version column excluded:
{ TOrderProperties }
TOrderProperties = record
public
ID: TTProperty;
OrderDate: TTProperty;
Notes: TTProperty;
class function Create: TOrderProperties; static;
end;
It gives compile-time checked column names to the expression API:
var
LOrder: TOrderProperties;
LFilter: TTFilter;
begin
LOrder := TOrderProperties.Create;
LFilter := Context.CreateFilterBuilder<TOrder>()
.Where(
(LOrder.OrderDate >= StartOfTheMonth(Today)) and
LOrder.Notes.IsNotNull)
.OrderByDesc(LOrder.OrderDate)
.Build;
Entity and entity list columns have no entry in the record.
API REST controllers¶
In a project created by the API REST wizard the option Generate & register API REST controllers is enabled; in any other project it is greyed out. When ticked, for each selected entity the Expert also:
-
writes a controller unit
<Project>.Controller.<Entity>in theControllersfolder of the project:The URI is the entity name in lower case;
-
opens
<Project>.Httpand registers the controllers: it adds the units to itsusesclause and aServer.RegisterController<TOrderController>();line toRegisterEntityControllers. Units and registrations already there are not added again, so the model can be regenerated with the option ticked.