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:
Filter
object - filter (WHERE clause) in the request, for example,var filter = Filter.And.Equal(userId, "Id")
- filter by column (property, attribute) Id.Order
object - sorting (ORDER BY clause) in the request.Paging
object - 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
EntityModel
to 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,Email
property.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 itsEmail
property value.var user = await SecurityUser.SelectByKeyAsync(userId);
string email = user.Email;