Entity

Entity is the main concept, and indeed at the heart of the architecture of, the AUA framework. Each entity is defined by a class that contains its features and its relation to other entities. Each entity has an identifier that can be of any Data Type allowed in .NET, or it can be a combination of two or more Data Types allowed therein (combination key) .

Add Entities

Each entity inherits from the DomainEntity class, to which a primary key field called Id and one or more monitoring fields (depending on the setting type) are added .


            
public  class  Student  :  DomainEntity
{
    public  string  FirstName  { get;  set; }
    public  string  LastName  { get;  set; }
    public  int  Age  { get;  set; }
}


It should be specified if the primary key has a data type other than the int data type (e.g. the Long data type is considered under the primary key)


            
public  class  Student : DomainEntity<long>
{
    public  string  FirstName  { get;  set; }
    public  string  LastName  { get;  set; }
    public  int  Age  { get;  set; }
}


By default the following fields are added to each entity. The Id key, the IsActive field and the RegistrationDate. The RegistrationDate displays the date and time the entity is created (automatically created inside SQL Server) and does not need to be filled in and sent .


            
public  class  DomainEntity<TPrimaryKey> : BaseDomainEntity<TPrimaryKey>, IAuditInfo
{
    public  DateTime  RegDate  { get;  set; }
}


The Id key of the primary key and its data type can be specified when defining an entity. The IsActive field shows whether the entity is active or inactive and it has a bool data type.


            
public  class  BaseDomainEntity<TPrimaryKey> : IDomainEntity<TPrimaryKey>
{
    public  TPrimaryKey  Id  { get;  set; }
    public  bool  IsActive  { get;  set; }
}

Entity Configs

There is a configuration class for each entity that can specify the length of field settings for it.


            
public  class  StudentConfig : IEntityTypeConfiguration<Student>
{

    public  void  Configure (EntityTypeBuilder<Student>  builder)
    {

        builder
           .Property(p => p.FirstName)
           .HasMaxLength(LengthConsts.MaxStringLen50);

        builder
           .Property(p => p.LastName)
           .HasMaxLength(LengthConsts.MaxStringLen50);

    }
}


We configure the entity with the combination key as follows. The AppUserId and RoleId fields are both keys to the UserRole entity.


            
public  class  UserRoleConfig : IEntityTypeConfiguration<UserRole>
{

    public  void  Configure (EntityTypeBuilder<UserRole> builder)
    {

        builder.Ignore(p => p.Id);

        builder.HasKey(p => new { p.AppUserId, p.RoleId });

    }

}


The entity without the identity key is configured as follows, in which case you send the initial value (Id) of the primary key to SQL Server.


            
public  class  UserAccessConfig : IEntityTypeConfiguration<UserAccess>
{

    public  void  Configure (EntityTypeBuilder<UserAccess>  builder)
    {
        builder
           .Property(p => p.Id)
           .ValueGeneratedNever();

        builder
            .Property(p => p.Title)
            .HasMaxLength(LengthConsts.MaxStringLen300);

        builder
           .Property(p => p.IsActive)
           .IsRequired();
    }
}


The entity is configured without registering the deleted load (logical deletion).


            
public  class  AppUserConfig : IEntityTypeConfiguration<AppUser>
{
    public  void  Configure(EntityTypeBuilder<AppUser>  builder)
    {
        builder.HasQueryFilter(p => p.IsDeleted);
    }
}


Optional features

Identities without an identity key are configured as follows, in which case the main key is sent to the database.


            
public class UserAccessConfig : IEntityTypeConfiguration<UserAccess>
{
    public void Configure(EntityTypeBuilder<UserAccess>  builder)
    {
        builder
            .Property(p => p.Id)
            .ValueGeneratedNever();
        
        builder
            .Property(p => p.Title)
            .HasMaxLength(LengthConsts.MaxStringLen300);
        
        builder
            .Property(p => p.IsActive)
            .IsRequired();
    }
}


Entity configuration, without considering deletion
            
public class AppUserConfig : IEntityTypeConfiguration<AppUser>
{

    public void Configure(EntityTypeBuilder<AppUser>  builder)
    {
        builder.HasQueryFilter(p => p.IsDeleted);  
    }

}


Audit Fields

Audit fields can vary from business to business. By default, the fields Id, IsActive, RegistrationDate and CreatorUserId are added to each entity. Yet, these are completely changeable. . You can have monitoring fields for each entity for logical deletion. If you implement the IDeletionAudited interface for an entity, the DeleterUserId, DeletionDate and IsDeleted fields will be added to that entity, and the record can be logically deleted using the SoftDelete function found in each service.

In Entity configuration, the default filter can be specified for deleted records. If you want to have logical deletion for all entities, you can implement the IDeletionAudited interface for DomainEntity . Logical and physical deletion can be combined. Monitoring fields are added to update a record by implementing the IModifiedAudited interface. After adding the IModifiedAudited interface, the ModifierUserId and ModifyDate fields are added to the entity .
You can add more monitoring fields to entities if you wish depending on your business. Monitoring Field creating the ICreationAudited Entity


            
public  interface  ICreationAudited
{
    long  CreatorUserId  { get;  set; }
}


To add the monitoring field of CreatorUserId, we can simply implement the ICreationAudited interface for the DomainEntity class , as follows:


            
 public  class  DomainEntity<TPrimaryKey> : BaseDomainEntity<TPrimaryKey>, IAuditInfo, ICreationAudited
 {
     public  DateTime  RegDate  { get;  set; }
     public  long  CreatorUserId  { get;  set; }
 }
 
 

Modified Audited


Soft Delete

The IDeletionAudited interface can be used to prevent the physical deletion and add the monitoring fields of entity deletion .


            
public  interface  IDeletionAudited : ISoftDelete
{
    long?  DeleterUserId  { get;  set; }
    DateTime?  DeleteDate  { get;  set; }
}

public  interface  ISoftDelete
{
    bool  IsDeleted  { get;  set; }
}


The IModifiedAudited interface can be used to add monitoring fields for editing an entity .


            
public  interface  IModifiedAudited
{
    long?  ModifierUserId  { get;  set; }
    DateTime?  ModifyDate  { get;  set; }
}

Soft Delete

Schema

One of the security issues in SQL Server is the schema of tables. By default, the names of tables are stored with the dbo prefix in the SQL Server. It is easily possible to customize this schema in the AUA framework. To manage and prevent the dispersal of constants in the program, we write them in the classes in a fixed order.


            
public  class  SchemaConsts
{
    public  const  string  Accounting  =  "Acc" ;
    public  const  string  School  =  "Sch" ;
}

            
[Table("Student", Schema = SchemaConsts.School)]
public  class  Student : DomainEntity
{
    public  string  FirstName  { get;  set; }
    public  string  LastName  { get;  set; }
    public  int  Age  { get;  set; }
}