專案需求:從資料庫讀取全國行政區域資料 (省/市/區三層),提供給前端下拉選單。資料表結構簡單:

使用代碼生成器 (動軟 .NET 代碼生成器 + CodePlex Stored Procedure Generator) 產生三層架構基礎代碼。
List<District> topDistrictList = new List<District>();
DistrictBLL dictrictBll = new DistrictBLL();
// 1. 查詢頂層 (父代碼 = 0)
topDistrictList = dictrictBll.GetEntityList(
string.Format("DisFatherCode='{0}' {1}", 0, Settings.District_Order_By));
// 2. 迴圈每個頂層,再查一次子節點 → N+1 次資料庫往返
foreach (District dis in topDistrictList)
{
dis.ChildrenDis = dictrictBll.GetEntityList(
string.Format("DisFatherCode='{0}' {1}", dis.DisCode, Settings.District_Order_By));
}
return topDistrictList;
結果:兩層資料耗時 ~5 秒 勉強可接受;三層資料飆升至 50 秒 完全無法上線。

List<District> districtList = new List<District>();
DistrictBLL dictrictBll = new DistrictBLL();
// 1. 單次查詢撈取頂層 + 次層所有資料 (WHERE 條件合併)
districtList = dictrictBll.GetEntityList(
string.Format(" {0} {1}", Settings.Get_Top_And_Second_District_Where, Settings.District_Order_By));
// 2. LINQ 記憶體分組組裝父子關係
var top = from c in districtList
where c.DisFatherCode.Trim() == "0"
select c;
var second = from c in districtList
where c.DisFatherCode.Trim() != "0"
select c;
foreach (District dis in top)
{
var se = from c in second
where c.DisFatherCode == dis.DisCode
select c;
dis.ChildrenDis = se.ToList<District>();
}
return top.ToList<District>();
效能躍升:
「不要多次往返資料庫」 — 每次連線/查詢/關閉都有固定開銷 (Connection Pooling 也無法消除網路往返與協定解析成本)。
「一次撈足量資料,C# 記憶體中組裝」 — 現代伺服器記憶體充裕,LINQ/PLINQ 處理物件圖極快,資料庫只負責「過濾與投影」。
下一篇將探討 快取策略:
HttpRuntime.Cache / MemoryCache 進階用法CacheDependency)SqlCacheDependency)