Code First Development Tutorials
The following tutorials demonstrate the code first approach. For tutorials using the database first approach, see DB First Development Tutorials.
Creating a weather forecast sample
We will walk you through the general process of creating a designer-developed project using the WeatherForecast template project.
In this demo, we will choose the "Web API" project type. This project type will generate back-end C# Web APIs only.
This project by default contains one entity, and provides APIs for adding/getting/editing/removing and filtering temperature data. You can directly generate and run C# projects without needing to modify this template project.
Step 1: Create a design project.
From File > New > New Project, select the Designer-developed tab; and then select Web API and click Next.
Keep the default settings and click Create.
The project displays in the solution explorer.
The project contains an entity design file WeatherForecast.dmedm which has the basic configurations.
Step 2 (Optional): Check and/or modify the WeatherForecast.dmedm entity.
You can double click the WeatherForecast.dmedm file to load and modify the entity settings in the Entity Designer.
The Entity Designer contains 4 tabs: Field Design, Filter Design, Service & API Design, and Code Preview. The Field Design tab contains the settings for fields; the Filter Design tab contains the settings for data filters and conditions; the Service & API Design tab specifies the APIs to be generated; the Code Preview tab allows you to view the automatically generated C# code in different modes (by category or by target).
Step 3: Generate projects from the design project.
Click the Generate Projects: Profile button on the IDE toolbar, or right click the project node, and then select Generate Projects > Profile.
When the project generation is successful, the following projects are generated based on the design project.
- [project].Common: the development toolkits and extension functions that are referenced or dependent by the Contracts or Identity projects.
- [project].Contracts: the contract layer which defines the contract for the service.
- [project].Controllers: the controller layer which defines the controller for the service.
- [project].Dal: the data access layer such as EF Core which contain the database-related configurations (repository, unit of work, DbContext) and data initialization (value comparers, value converters).
- [project].Services: the service layer which implements the contracts.
- [project].WebApi: the representation layer which sends data to users.
- [project].Identity: the authentication service layer which authorizes the user registration and login internally. This project will be generated only when you enable the authorization.
Step 4: Run the projects.
Run the [project].WebApi project to start the Web APIs.
When Web APIs starts, the database file (data.db) will be generated automatically.
When the Web APIs runs successfully, you will be able to see the Swagger UI and test the basic APIs and the filter APIs on the Swagger UI.
For example, you can expand the Add API, and add data.
Creating an employee management demo
Introduction
This tutorial uses a demo application to explain how you develop applications using the visual designers in DevMagic Studio. Please get the demo application from this link: https://github.com/DevMagicStudio/LowCode-EmployeeManager-Beta-Example.
Operations
This demo application generates the APIs for performing the following operations:
- Add, edit, delete, view companies
- Add, edit, delete, view departments
- Add, edit, delete, view employees
- Filter companies or employees
Overall design concepts
Entities
Creates two base entities: BaseEntity and SoftDelete, for holding fields that are re-used frequently.
BaseEntity: Contains the following frequently-used fields: id, Creator, CreateTime, Updator, UpdateTime.
SoftDelete: Inherits from BaseEntity and contains an additional field: IsDeleted. When a department is deleted, IsDeleted will be set to True and the department will be invisible to the user (data is still kept in the database).
Creates an owned entity: Address, for holding the following fields: City, Town, Street. The Address entity will be referenced by HomeAddress in the Employee entity and CompanyAddress in the Company entity.
Creates three standard entities: Employee, Department, Company.
Relations
One company can have only one contactor, and one contactor can belong to only one company.
One company can have one or more employees, and one employee can belong to only one company.
One company can have one or more departments, and one department can belong to one or more one companies.
One department can have one or more employees, and one employee must belong to and can only belong to one department.
Enums
The Gender enumeration type is created and contains two fixed values: Female and Male.
The CompanySize enumeration type is created and contains four fixed values: Tiny, Small, Big, Large.
Filters
Filter employees by different conditions.
For example, to filter data by phone or by name
Two parameters are added: Keywords (to match with the first name or last name field), Phone (to match with the phone field)
To match the keywords with either the first name or the last name field, use "Scope".
For another example, to filter data by department, gender, or IsTrial
Three parameters are added: Department, Gender, IsTrial.
The default value of the IsTrial parameter is set to False, which means employees during probation period will not be searched, only regular employees will. The IsTrial field value is a dynamic value calculating based on the HireDate and TrialMonths fields. The expression can make references to the entity, filter, filter parameter, enumeration, built-in functions etc. Take the following expression for example, Employee is the entity that owns the filter, DepartmentUser is the filter name, IsTrial is the filter parameter.
(DateDif(Employee.HireDate, Now(), 'M') < Employee.TrialMonths) == Employee.DepartmentUser.IsTrial
Development process
The following is a detailed step-by-step guide for developing the demo application.
Create a design project
In DevMagic Studio, select File > New > New project > Web API.
If you have downloaded the demo application, you may open it directly in the DevMagic Studio.
Create and design the enumeration type
Right-click the project and select Add > New Item > Enum Design, to add the following enumerators: Gender and CompanySize.
In the demo application, you may open Enums > Gender.dme and CompanySize.dme and see how they are designed.
The Gender.dme file defines two values: Male and Female.
The CompanySize.dme file defines four values: Tiny, Small, Big, Large.
Create and design the base entity
Right-click the project and select Add > New Item > Base Entity Design to add the following base entities: BaseEntity and SoftDelete.
In the demo application, you may open Entities > Bases > BaseEntity.dmedm and SoftDelete.dmedm and see how they are designed.
BaseEntity entity
The BaseEntity entity is the base class for all other entities in this project. It contains the fields that are commonly used by the other entities, such as Id (primary key), Creator, CreateTime, Updator, UpdateTime.
The following outlines the key steps to design the BaseEntity entity:
Step 1: Set the Id field as the primary key.
Step 2: Set the value for Creator to the current user using the $ICurrentUser.GetUserId()
expression and select Execute on insert option to execute the expression on insert.
You will need to enable authorization first before you can use the ICurrentUser functions.
Step 3: Set the value for CreateTime to the current time using the UtcNow()
expression and select Execute on insert option to execute the expression on insert.
Step 4: Set the value for Updator to the current user using the $ICurrentUser.GetUserId()
expression and select both the Execute on insert and Execute on update options to execute the expression on insert and update.
Step 5: Set the value for UpdateTime to the current time using the UtcNow()
expression and select both the Execute on insert and Execute on update options to execute the expression on insert and update.
SoftDelete entity
The SoftDelete entity inherits from the BaseEntity, and contains an IsDeleted field. When a department is deleted, IsDeleted will be set to True and the department will be invisible to the user (data is still kept in the database).
Create and design the owned entity
Right-click the project and select Add > New Item > Owned Entity Design to add the following entity: Address.
In the demo application, you may open Entities > Bases > Address.dmedm and see how it is designed.
The Address entity defines three fields: City (required), Town (nullable), Street (required).
Create and design the entity
Right-click the project and select Add > New Item > Entity Design (from Scratch) to add the following entities: Company, Department, Employee.
Company.dmedm will contain the following fields: CompanyName, Contactor, CompanySize, CompanyAddress, EmployeeList, EmployeeCount (and fields such as Id inherited from BaseEntity).
Department.dmedm will contain the following fields: DepartmentName, Company, SuperiorDepartment (and fields such as IsDeleted inherited from SoftDelete).
Employee.dmedm will contain the following fields: FirstName, LastName, FullName, Gender, PhoneNumber, HireDate, TrialMonths, IsTrial, HomeAddress, Department, Company, Manager, IsManager (and fields such as Id inherited from BaseEntity)
The field settings will be set and explained in the following sections. If you have downloaded the demo application, you may open the Entities > Company.dmedm, Department.dmedm, and Employee.dmedm files to view the field settings.
Company entity
The Company entity contains the fields as shown below.
The following outlines the key steps to design the Company entity settings:
Field Design
Step 1: Set the Company entity to inherit from BaseEntity.
The fields of BaseEntity will be shown as readonly if the Show inherited fields option is checked.
Step 2: Set the CompanyName field as the required field, and specify the minimum and maximum length if necessary.
Step 3: Configure the Contactor field:
- Set the Contactor field to reference to the Employee entity and select the Nullable option.
- On the right panel, select One to One from the Relations list, select Employee from the Mapped to list, select Set null from the Delete rule list, and select the Generate foreign key field option.
Step 4: Set the field type for CompanySize to the CompanySize enumeration type.
Step 5: Set the CompanyAddress field to reference to the Address owned entity.
Step 6: Configure the EmployeeList field:
- Set the EmployeeList field to reference to the Employee entity and select the Collection option.
- On the right panel, select One to Many from the Relations list, select Employee.Company from the Mapped to list, and select Cascade delete from the Delete rule list.
Step 7: Set the EmployeeCount field to the Compute type, and then on the right panel, add the following computed expressions and set the data type to Int32.
Count(Company.EmployeeList)
Filter Design
Step 1: Select the Filter Design tab, and create a filter named FilterByAddressAndCompanySize.
Service & API Design
Step 1: Select Add service > Get single data > With PrimaryKeyFilter to create the service and change the service name to Get.
Step 2: Select Add service > Get list data > With NoFilter to create the service and change the service name to GetList.
On the Service Settings tab, select the CascadeQuery option for EmployeeList in the Return Settings section. Click Choose a data source to sort and select EmployeeList, click Add sort option to select DepartmentID and Ascending, click Add sort option again to select FirstName and Ascending.
Step 3: Select Add service > Get paged data > With FilterByAddressAndCompanySize to create the service and change the service name to GetPage.
Step 4: Select Add service > Add single data to create the Add service.
Step 5: Select Add service > Update single data to create the Update service.
Step 6: Select Add service > Delete single data to create the Delete service.
Step 7: Select Generate all APIs to automatically generate APIs for all these services.
Department entity
The Department entity contains the fields as shown below.
The following outlines the key steps to design the Department entity settings:
Field Design
Step 1: Set the Department entity to inherit from SoftDelete.
And the fields of SoftDelete will be shown as readonly if the Show inherited fields option is checked.
Step 2: Set the DepartmentName field as the required field, and specify the minimum and maximum length if necessary.
Step 3: Configure the Company field:
Set the Company field to reference to the Company entity and select the Collection options.
On the right panel, select Many to Many from the Relations list, select Company from the Mapped to list, and select the Generate foreign key field option.
Step 4: Configure the SuperiorDepartment field:
Set the SuperiorDepartment field to reference to the Department entity.
Select the Nullable option, so a new department can be added successfully without needing to specify the superior department.
And then on the right panel, select Many to One from the Relations list, select Department from the Mapped to list, and select Set null from the Delete rule list (so when the superior department is deleted, the SuperiorDepartment field in the child department will be set to null), and select the Generate foreign key field option.
Note: for a SQL Server database, if a field is associated with the entity that the field belongs to, the delete strategy can only be set to No action, otherwise, a database error will occur.
Service & API Design
Step 1: Select Add base services to automatically generate the services.
Step 2: Select Generate all APIs to automatically generate APIs for the services.
Employee entity
The Employee entity contains the fields as shown below.
The following outlines the key steps to design the Employee entity settings. In the demo application, you can open the Entity > Employee.dmedm file to view all of the settings.
Field Design
Step 1: Set the Employee entity to inherit from BaseEntity.
Step 2: Set the FirstName, LastName and PhoneNum as required fields, and on the right panel, set the minimum and maximum length as you need, add the following regular validation expression to the PhoneNum field.
^(\+|00)[0-9]{1,4}[ ,-]?[0-9]{4,14}(?:x.+)?$
Step 3: Set the FullName field to the Compute type, and on the right panel, select the String data type and add the following computed expression.
(Employee.FirstName + ' ') + Employee.LastName
Step 4: Set the field type for Gender to the Gender enumeration type.
Step 5: Set the field type for HireDate to DateTime, and the default value to the current time using the Now()
expression.
Step 6: Set the field type for TrialMonths to Int32, and the default value to 3 and maximum value to 36 (or any value you like).
Step 7: Set the IsTrial field to the Compute type, and on the right panel, select the Boolean data type and add the following computed expression.
DateDif(Employee.HireDate, Now(), 'M') < Employee.TrialMonths
Step 8: Set the HomeAddress field to reference to the Address entity.
Step 9: Configure the Department field:
- Set the Department field to reference to the Department entity.
- On the right panel, select Many to One from the Relations list, select Department from the Mapped to list, select Default from the Delete rule list, and select the Generate foreign key field option.
Step 10: Configure the Company field:
- Set the Company field to reference to the Company entity.
- On the right panel, select Many to One from the Relations list, select Company.EmployeeList from the Mapped to list, select Cascade delete from the Delete rule list, and select the Generate foreign key field option.
Step 11: Configure the Manager field:
- Set the Manager field to reference to the Employee entity and select the Nullable option.
- On the right panel, select Many to One from the Relations list, select Employee from the Mapped to list, select Set null from the Delete rule list, and select the Generate foreign key field option.
Note: for a SQL Server database, if a field is associated with the entity that the field belongs to, the delete strategy can only be set to No action, otherwise, a database error will occur.
Step 12: Set the IsManager field to the Compute type, and on the right panel, select the Boolean data type and add the following computed expression.
IsNull(Employee.Manager)
Filter Design
Step 1: Select the Filter Design tab, and create the following filters.
Create a filter named GenericSearch for filtering the employee by name or phone number.
Note that it uses Scope to match the input name with either FirstName or LastName.
When you design the filter, you can preview the filter syntax on the right panel.
Create a filter named DepartmentUser for filtering the employee by department, gender or IsTrial.
(DateDif(Employee.HireDate, Now(), 'M') < Employee.TrialMonths) == Employee.DepartmentUser.IsTrial
The default value of the IsTrial parameter is set to False, which means employees during probation period will not be searched, only regular employees will.
Create a filter named ManagerFilter for filtering the manager by company and IsManager.
IsNull(Employee.Manager)
Create a filter named EmployFilter for filtering the employee by company, department, or manger.
Service & API Design
Step 1: Select Add service > Get list data > With ManagerFilter to create the service and change the service name to GetManagers.
Step 2: Select Add service > Get single data > With PrimaryKeyFilter to create the service and change the service name to Get.
Step 3: Select Add service > Get paged data > With GenericSearch to create the service and change the service name to GetPage.
Step 4: Select Add service > Get list data > With EmployFilter to create the service and change the service name to GetEmployees.
Step 5: Select Add service > Get paged data > With DepartmentUser to create the service and change the service name to GetDepartmentEmployees.
Step 6: Select Add service > Add single data to create the Add service.
Step 7: Select Add service > Update single data to create the Update service.
Step 8: Select Add service > Get list data > With NoFilter to create the service and change the service name to GetList.
Step 9: Select Add service > Delete single data to create the Delete service.
Step 10: Select Generate all APIs to automatically generate APIs for all these services.
Generate & run projects
Select Generate Projects: Profile from the IDE toolbar, or right click on the project node and then select Generate Projects > Profile.
After the projects are generated successfully, run the [project].WebApi project to start the Web APIs.
When the Web APIs runs successfully, you will be able to see the Swagger UI.
For example, you can add a department by expanding the /API/Company/Add API, clicking Try it out, modifying the CompanyName to "ABC" in the Request body, and then clicking Execute.
If you have enabled authorization, you will need to register an account, log in with the account to obtain the access token, click Authorize and enter the access token, before you can execute the Web APIs.