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

實戰聚合模式:將 Card 與 CardKind 實體合一,告別重複查詢

     編輯:關於.NET

典型場景:Card 表關聯 CardKind 表,顯示列表時需要卡類型名稱而非 ID。若僅使用代碼生成器產出的表實體(僅含 CardKindId),將陷入「查詢 → 發現缺名稱 → 重寫 SQL Join → 綁定 → 詳情再查」的惡性循環。本文展示如何通過實體聚合一次性解決。

初始狀態:貧血表實體

代碼生成器產出 Card、CardKind 兩獨立類,Card 僅持有 decimal CardKindId。列表 DTO 需 CardKindName,無法直接綁定。

聚合重構:Card 擁有 CardKind

public class Card
{
    // 刪除原 CardKindId
    // private decimal m_CardKindId;
    // public decimal CardKindId { get; set; }

    // 引入聚合對象
    private CardKind m_CardKind;
    public CardKind CardKind 
    { 
        get { return m_CardKind; } 
        set { m_CardKind = value; } 
    }

    // 克隆需深拷貝聚合對象
    public new Card Clone()
    {
        Card card = base.Clone() as Card;
        card.m_CardKind = this.CardKind?.Clone(); // 假設 CardKind 實現 Clone
        return card;
    }
}

數據訪問層調整:一次查詢填充聚合

// SQL 使用 JOIN 一次取回所有字段
SELECT c.*, k.CardKindName, k.IsValid 
FROM Card c 
INNER JOIN CardKind k ON c.CardKindId = k.CardKindId

// 映射邏輯(伪代碼)
var card = new Card { 
    CardId = reader["CardId"], 
    StartNO = reader["StartNO"], 
    EndNO = reader["EndNO"],
    CardKind = new CardKind { 
        CardKindId = reader["CardKindId"], 
        CardKindName = reader["CardKindName"], 
        IsValid = reader["IsValid"] 
    }
};

收益

  • 列表綁定直接用 card.CardKind.CardKindName,無額外查詢。
  • 詳情彈窗同樣複用同一聚合對象,避免二次查庫。
  • 領域模型更豐富:Card 擁有 CardKind,符合業務語義(一張卡「屬於」一種類型)。
  • 克隆、序列化等操作自動級聯處理關聯數據。

核心啟示

不要讓數據庫表結構直接決定領域模型。 表實體 ≠ 業務實體。聚合根(Aggregate Root)應封裝業務不變量與關聯導航,一次加載滿足多種使用場景。

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