首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

C# 多型實戰:學生資訊管理系統中統一處理多種資料實體

     編輯:關於.NET

專案需對 8 類學生資訊 (基本、家庭、獎學金、活動、資助、處分、素質測評、比賽) 進行 CRUD,每類對應一資料表、一實體、一 WinForm 編輯視窗。透過繼承基底表單 Form_Base 並定義虛擬方法 ConstructEntityInfo(),實現「統一流程、個別實作」的多型架構。

領域模型概覽

  • 基本資料:學號、姓名、班級、專業、年齡、身分證、籍貫
  • 家庭資料:地址、電話、成員
  • 獎學金:金額、時間、項目
  • 活動:名稱、時間、結果
  • 資助:項目、金額、時間
  • 處分:時間、原因、撤銷狀態
  • 素質測評:時間、文體項目得分
  • 比賽:名稱、時間、結果

基底表單 Form_Base 核心邏輯

public partial class Form_Base : Form
{
    protected StudentManagerDataContext Context { get; private set; }
    protected DataGridView GridView { get; set; } // 回寫清單
    protected object Entity { get; set; }         // 編輯時的實體
    protected bool IsEdit { get; private set; }

    public Form_Base() { }

    public Form_Base(object entity)
    {
        if (entity != null) { IsEdit = true; Entity = entity; }
        Context = new StudentManagerDataContext(AppInfo.ConnectionString);
    }

    // 統一的新增/修改流程
    protected void AddOrEditInfo()
    {
        try
        {
            if (ISLegal())
            {
                ConstructEntityInfo(); // 多型進入點
                SMSApplication.ShowOperateSucceedResult();
            }
            else ShowHandleEntityError(null);
        }
        catch (FormatException ex) { /* 格式錯誤友善提示 */ }
        catch (OverflowException ex) { /* 溢位錯誤友善提示 */ }
        catch (Exception ex) { ShowHandleEntityError(ex.Message); }
        finally { this.Dispose(); }
    }

    // 由子類實作具體實體建構/更新邏輯
    protected virtual void ConstructEntityInfo()
    {
        throw new NotImplementedException();
    }

    protected bool ISLegal() => DataPool.StudentNumber != "0";
    // ... 錯誤處理輔助方法
}

子類實作範例:比賽資訊 Form_Game

public partial class Form_Game : Form_Base
{
    private Game game = new Game();

    public Form_Game(DataGridView view, object entity) : base(entity)
    {
        GridView = view; Entity = entity;
        InitializeComponent();
        if (IsEdit)
        {
            game = entity as Game;
            dateTimePicker_GameTime.Text = game.GameDateTime.ToString();
            textBox_GameName.Text = game.GameName;
            textBox_GameResult.Text = game.GameResult;
        }
    }

    private void button_AddGame_Click(object sender, EventArgs e)
    {
        AddOrEditInfo(); // 呼叫基底統一流程
    }

    protected override void ConstructEntityInfo()
    {
        if (IsEdit)
            game = (from g in Context.Games where g.GameID == ((Game)Entity).GameID select g).Single();

        game.GameResult = textBox_GameResult.Text;
        game.GameName = textBox_GameName.Text;
        game.GameDateTime = Convert.ToDateTime(dateTimePicker_GameTime.Text);

        if (!IsEdit)
        {
            game.StudentNumber = DataPool.StudentNumber;
            Context.Games.InsertOnSubmit(game);
        }
        Context.SubmitChanges();
        GridView.DataSource = GetIQueryable.GetGameQueryable(Context);
    }
}

子類實作範例:資助資訊 Form_Support

public partial class Form_Support : Form_Base
{
    private StudentSupport support = new StudentSupport();

    public Form_Support(DataGridView gridview, object entity) : base(entity)
    {
        GridView = gridview; Entity = entity;
        InitializeComponent();
        if (IsEdit)
        {
            support = entity as StudentSupport;
            dateTimePicker_SupportTime.Text = support.SupportTime.ToShortDateString();
            textBox_SupportAmount.Text = support.SupportAmount.ToString();
            textBox_SupportRemark.Text = support.SupportRemark;
            textBox_SupportSource.Text = support.SupportFrom;
        }
    }

    private void button_AddSupport_Click(object sender, EventArgs e) => AddOrEditInfo();

    protected override void ConstructEntityInfo()
    {
        if (IsEdit)
            support = (from s in Context.StudentSupports where s.SupportID == ((StudentSupport)Entity).SupportID select s).Single();

        support.SupportAmount = Convert.ToInt32(textBox_SupportAmount.Text);
        support.SupportFrom = textBox_SupportSource.Text;
        support.SupportRemark = textBox_SupportRemark.Text;
        support.SupportTime = Convert.ToDateTime(dateTimePicker_SupportTime.Text);

        if (!IsEdit)
        {
            support.StudentNumber = DataPool.StudentNumber;
            Context.StudentSupports.InsertOnSubmit(support);
        }
        Context.SubmitChanges();
        GridView.DataSource = GetIQueryable.GetSupportQueryable(Context);
    }
}

架構優勢

  1. 消除重複: 驗證、例外處理、Context 管理、UI 回寫集中於基底。
  2. 開放封閉原則: 新增資料類別只需新增子類並實作 ConstructEntityInfo,不修改基底。
  3. 型別安全: 子類強型別存取自有實體屬性,編譯期檢查。
  4. 可測試性: 邏輯集中於虛擬方法,易於單元測試 Mock。

改進建議

  • 將 GridView = view; Entity = entity; 移至基底建構子,避免子類重複賦值。
  • 考慮引入 Repository 模式抽象 Context 操作,降低對 LINQ to SQL 的耦合。
  • 使用介面 IEntityEditor 定義編輯契約,配合 DI 容器管理視窗建立。

此多型實作展示了「模板方法模式」在 WinForms 資料編輯場景的經典應用,有效平衡了共性流程與個性邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved