ORM architecture

DWKit uses a special ORM engine that allows getting data represented as dynamic objects or strongly typed objects inherited
from DbObject<T>, where T refers to the type of object. To request and update information in the database, you need information about
what tables you should request, types of columns, and how to build joins. In other words, you need metadata. In DWKit this metadata is
represented by an EntityModel object. You can get this information from three sources:
- Using Data Model, which you can change and synchronize in the admin panel. In this case, you should request data object by the DataModel object name.
- Using Form and data mapping, which can be edited in the admin panel. In this case, you should request data object by the Form name.
- Using information from the attributes which mark properties of the class inherited from
DbObject<T>.
In first two cases, getting a model is provided by MetadataToModelConverter static class, in the third case - by DbObject<T>.Model
property. Below is an example of getting EntityModel from Data Model:
EntityModel userModel = await MetadataToModelConverter.GetEntityModelByModelAsync("SecurityUser");
In this case, the EntityModel provides access to the SecurityUser table in the database.
An example of getting the EntityModel from the Form:
EntityModel userModel = await MetadataToModelConverter.GetEntityModelByFormAsync("SecurityUserForm");
In this case, EntityModel provides access to SecurityUser table and additional data (for example, to collections), described in
the form and data mapping.
Here's an example of getting EntityModel from DbObject<T>:
public class SecurityUser : DbObject<SecurityUser>
{
[DbObjectModel(IsKey = true)]
public Guid Id
{
get => _entity.Id;
set => _entity.Id = value;
}
[DbObjectModel]
public string Name
{
get => _entity.Name;
set => _entity.Name = value;
}
[DbObjectModel]
public string Email
{
get => _entity.Email;
set => _entity.Email = value;
}
}
EntityModel securityUserModel = SecurityUser.Model;
In this case, EntityModel provides access to SecurityUser table in the database. Table name and columns names match class name and
properties names.
Thus, using EntityModel, you can request or update data. Usually, such operations are performed using DynamicRepository static object or
using EntityModel instance. For example:
var userModel = await MetadataToModelConverter.GetEntityModelByModelAsync("SecurityUser");
var user = (await userModel.GetAsync(Filter.And.Equal(userId, "Id"))).FirstOrDefault();
or using class static methods, inherited from DbObject<T>. For example, using SecurityUser class, described above:
var user = await SecurityUser.SelectByKeyAsync(userId);
First approach is used to organize general business logic. For example, DWKit uses it to organize data sources for forms. Second approach is used to organize complicated and unique algorithms of business logic.
When requesting data, you can specify request parameters:
Filterobject - filter (WHERE clause) in the request, for example,var filter = Filter.And.Equal(userId, "Id")- filter by column (property, attribute) Id.Orderobject - sorting (ORDER BY clause) in the request.Pagingobject - specification of data page in the request.
You can also change or update data using the DynamicRepository object or using EntityModel. Upon data selection, you get objects of two
types:
-
In case you used
EntityModelto request data, you will get a list or a unique object, such asDynamicEntity. There are two ways of getting values of properties from them. For example,Emailproperty.string email = (string)user["Email"];or using conversion to
dynamic:var dynamicUser = user as dynamic;
string email = user.Email; -
In case you used
DbObject<T>inheritor to request data, data will be strongly typed. For example, you can getUser- as an object and get itsEmailproperty value.var user = await SecurityUser.SelectByKeyAsync(userId);
string email = user.Email;