新增 SpaceBookingDbContext 類別及其配置
新增 `SpaceBookingDbContext` 類別,繼承自 `DbContext`,定義了 `Departments`、`Roles` 和 `Accounts` 資料集。實作模型配置方法以設定資料表名稱、主鍵、欄位屬性及外鍵關聯。覆寫 `SaveChanges` 和 `SaveChangesAsync` 方法,自動更新 `UpdatedAt` 欄位的時間戳記,確保 `CreatedAt` 在新增時不被修改。
This commit is contained in:
parent
1897e076c2
commit
2b8df04ece
@ -0,0 +1,255 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models.Entities;
|
||||
using XisongSpaceBooking_BackEnd.Models.Entities;
|
||||
|
||||
namespace XisongSpaceBooking_BackEnd.Configurations
|
||||
{
|
||||
/// <summary>
|
||||
/// 空間預約系統的資料庫內容類別
|
||||
/// </summary>
|
||||
public class SpaceBookingDbContext : DbContext
|
||||
{
|
||||
public SpaceBookingDbContext(DbContextOptions<SpaceBookingDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 處室資料集
|
||||
/// </summary>
|
||||
public DbSet<DepartmentEntity> Departments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份資料集
|
||||
/// </summary>
|
||||
public DbSet<RoleEntity> Roles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帳號資料集
|
||||
/// </summary>
|
||||
public DbSet<AccountEntity> Accounts { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// 配置 Department 實體
|
||||
ConfigureDepartment(modelBuilder);
|
||||
|
||||
// 配置 Role 實體
|
||||
ConfigureRole(modelBuilder);
|
||||
|
||||
// 配置 Account 實體
|
||||
ConfigureAccount(modelBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 Department 實體
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">模型建構器</param>
|
||||
private static void ConfigureDepartment(ModelBuilder modelBuilder)
|
||||
{
|
||||
var entity = modelBuilder.Entity<DepartmentEntity>();
|
||||
|
||||
// 設定資料表名稱
|
||||
entity.ToTable("departments");
|
||||
|
||||
// 設定主鍵
|
||||
entity.HasKey(d => d.DepartmentId);
|
||||
entity.Property(d => d.DepartmentId)
|
||||
.HasColumnName("department_id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasComment("處室 ID");
|
||||
|
||||
// 設定處室名稱
|
||||
entity.Property(d => d.DepartmentName)
|
||||
.HasColumnName("department_name")
|
||||
.HasMaxLength(20)
|
||||
.IsRequired()
|
||||
.HasComment("處室名稱");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 Role 實體
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">模型建構器</param>
|
||||
private static void ConfigureRole(ModelBuilder modelBuilder)
|
||||
{
|
||||
var entity = modelBuilder.Entity<RoleEntity>();
|
||||
|
||||
// 設定資料表名稱
|
||||
entity.ToTable("roles");
|
||||
|
||||
// 設定主鍵
|
||||
entity.HasKey(r => r.RoleId);
|
||||
entity.Property(r => r.RoleId)
|
||||
.HasColumnName("role_id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasComment("身份 ID");
|
||||
|
||||
// 設定身份名稱
|
||||
entity.Property(r => r.RoleName)
|
||||
.HasColumnName("role_name")
|
||||
.HasMaxLength(20)
|
||||
.IsRequired()
|
||||
.HasComment("身份名稱");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 Account 實體
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">模型建構器</param>
|
||||
private static void ConfigureAccount(ModelBuilder modelBuilder)
|
||||
{
|
||||
var entity = modelBuilder.Entity<AccountEntity>();
|
||||
|
||||
// 設定資料表名稱
|
||||
entity.ToTable("accounts");
|
||||
|
||||
// 設定主鍵
|
||||
entity.HasKey(a => a.AccountId);
|
||||
entity.Property(a => a.AccountId)
|
||||
.HasColumnName("account_id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasComment("帳號 ID");
|
||||
|
||||
// 設定使用者姓名
|
||||
entity.Property(a => a.Name)
|
||||
.HasColumnName("name")
|
||||
.HasMaxLength(20)
|
||||
.IsRequired()
|
||||
.HasComment("使用者姓名");
|
||||
|
||||
// 設定帳號名稱(唯一)
|
||||
entity.Property(a => a.Username)
|
||||
.HasColumnName("username")
|
||||
.HasMaxLength(20)
|
||||
.IsRequired()
|
||||
.HasComment("帳號名稱");
|
||||
|
||||
// 設定密碼
|
||||
entity.Property(a => a.Password)
|
||||
.HasColumnName("password")
|
||||
.HasMaxLength(255)
|
||||
.IsRequired()
|
||||
.HasComment("密碼(加密)");
|
||||
|
||||
// 設定電子郵件(唯一)
|
||||
entity.Property(a => a.Email)
|
||||
.HasColumnName("email")
|
||||
.HasMaxLength(50)
|
||||
.IsRequired()
|
||||
.HasComment("電子郵件");
|
||||
|
||||
// 設定處室 ID(外鍵)
|
||||
entity.Property(a => a.DepartmentId)
|
||||
.HasColumnName("department_id")
|
||||
.IsRequired()
|
||||
.HasComment("處室 ID");
|
||||
|
||||
// 設定身份 ID(外鍵)
|
||||
entity.Property(a => a.RoleId)
|
||||
.HasColumnName("role_id")
|
||||
.IsRequired()
|
||||
.HasComment("身份 ID");
|
||||
|
||||
// 設定帳號狀態(轉換為字串儲存)
|
||||
entity.Property(a => a.Status)
|
||||
.HasColumnName("status")
|
||||
.HasConversion(
|
||||
v => v.ToString().ToLower(),
|
||||
v => Enum.Parse<AccountStatus>(v, true))
|
||||
.HasMaxLength(20)
|
||||
.HasDefaultValue(AccountStatus.Unverified)
|
||||
.IsRequired()
|
||||
.HasComment("帳號狀態");
|
||||
|
||||
// 設定 BaseEntity 屬性
|
||||
entity.Property(a => a.CreatedAt)
|
||||
.HasColumnName("created_at")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP")
|
||||
.IsRequired()
|
||||
.HasComment("建立時間");
|
||||
|
||||
entity.Property(a => a.UpdatedAt)
|
||||
.HasColumnName("updated_at")
|
||||
.ValueGeneratedOnUpdate()
|
||||
.HasComment("更新時間");
|
||||
|
||||
entity.Property(a => a.ModifiedBy)
|
||||
.HasColumnName("modified_by")
|
||||
.IsRequired(false)
|
||||
.HasComment("最後修改者帳號 ID");
|
||||
|
||||
// 設定唯一索引
|
||||
entity.HasIndex(a => a.Username)
|
||||
.IsUnique()
|
||||
.HasDatabaseName("IX_accounts_username");
|
||||
|
||||
entity.HasIndex(a => a.Email)
|
||||
.IsUnique()
|
||||
.HasDatabaseName("IX_accounts_email");
|
||||
|
||||
// 設定外鍵關聯
|
||||
entity.HasOne(a => a.Department)
|
||||
.WithMany()
|
||||
.HasForeignKey(a => a.DepartmentId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.HasConstraintName("FK_accounts_departments");
|
||||
|
||||
entity.HasOne(a => a.Role)
|
||||
.WithMany()
|
||||
.HasForeignKey(a => a.RoleId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.HasConstraintName("FK_accounts_roles");
|
||||
|
||||
// 設定自參考外鍵(ModifiedBy)
|
||||
entity.HasOne<AccountEntity>()
|
||||
.WithMany()
|
||||
.HasForeignKey(a => a.ModifiedBy)
|
||||
.OnDelete(DeleteBehavior.SetNull)
|
||||
.HasConstraintName("FK_accounts_modified_by");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 覆寫 SaveChanges 以自動更新 UpdatedAt 欄位
|
||||
/// </summary>
|
||||
public override int SaveChanges()
|
||||
{
|
||||
UpdateTimestamps();
|
||||
return base.SaveChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 覆寫 SaveChangesAsync 以自動更新 UpdatedAt 欄位
|
||||
/// </summary>
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
UpdateTimestamps();
|
||||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新時間戳記
|
||||
/// </summary>
|
||||
private void UpdateTimestamps()
|
||||
{
|
||||
var entries = ChangeTracker.Entries<BaseEntity>();
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
switch (entry.State)
|
||||
{
|
||||
case EntityState.Added:
|
||||
entry.Entity.UpdatedAt = DateTime.UtcNow;
|
||||
break;
|
||||
|
||||
case EntityState.Modified:
|
||||
entry.Entity.UpdatedAt = DateTime.UtcNow;
|
||||
// 確保 CreatedAt 不會被修改
|
||||
entry.Property(e => e.CreatedAt).IsModified = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user