Entity Design
Art Admin uses EF Core as the ORM with MySQL 8.0. Entity classes follow a set of conventions.
Base Classes
EntityBase
csharp
public class EntityBase
{
public long Id { get; set; }
public DateTime CreatedTime { get; set; }
}EntityBaseWithUpdate
csharp
public class EntityBaseWithUpdate : EntityBase
{
public DateTime? UpdatedTime { get; set; }
}Entity Definition Example
csharp
[Table("sys_user")]
public class SysUser : EntityBaseWithUpdate
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string? Nickname { get; set; }
public string? Avatar { get; set; }
public int Status { get; set; }
public long? RoleId { get; set; }
public string? TenantId { get; set; }
[ForeignKey(nameof(RoleId))]
public SysRole? Role { get; set; }
}Key Conventions
ID Strategy
- All IDs use
longtype - Generated by Snowflake ID algorithm via
IdGen.NextId() - Framework auto-handles frontend precision (see JSON Serialization)
Table Name Mapping
csharp
[Table("sys_user")] // Explicitly specify table name
public class SysUser : EntityBaseWithUpdate { }Column Naming
EF Core is configured with snake_case naming convention. Property RoleId maps to column role_id.
Navigation Properties
Use [ForeignKey] with nameof() for type-safe navigation:
csharp
public long? RoleId { get; set; }
[ForeignKey(nameof(RoleId))]
public SysRole? Role { get; set; }Important
Database does NOT create foreign key constraints. [ForeignKey] only tells EF Core the relationship for navigation property loading. No actual FK constraint in MySQL.
Query with Navigation
csharp
var users = await _db.SysUsers
.Include(x => x.Role) // Load role data
.Where(x => x.Status == 1)
.Select(x => new UserDto
{
Id = x.Id,
Username = x.Username,
RoleName = x.Role!.Name // Access navigation property
})
.ToListAsync();Registering Entities
All entities must be registered in ArtDbContext:
csharp
public class ArtDbContext : DbContext
{
public DbSet<SysUser> SysUsers => Set<SysUser>();
public DbSet<SysRole> SysRoles => Set<SysRole>();
public DbSet<SysMenu> SysMenus => Set<SysMenu>();
// ...
}