ABP Suite:自訂 Entity Consts 的最佳做法
為什麼要修改模板
ABP Suite 會根據「實體欄位」自動產生:
XXXConsts類別MaxLength常數(例如PoNoMaxLength = 50)預設排序方法(
GetDefaultSorting)
但是:
每次重新產生 CRUD 時,
XXXConsts.cs都會被覆寫如果你在其中加入自訂常數(例如工廠代號、固定清單、domain rule),就會消失
為了避免覆蓋,你需要:
調整 Suite 的模板,讓
XXXConsts改成partial class使用外部
partial擴充檔案放常數
修改 Server.Entity.EntityConsts.txt
在 Suite 介面中編輯模板:
Templates → MVC → EfCore → Server.Entity.EntityConsts.txt
確保模板內容為:
namespace <solution-namespace>.<entity-namespace>
{
public static partial class <entity-name>Consts
{
private const string DefaultSorting = "<default-sorting>";
public static string GetDefaultSorting(bool withEntityName)
{
return string.Format(DefaultSorting, withEntityName ? "<entity-name>." : string.Empty);
}
<consts>
}
}
使用 Partial Class 擴充自訂常數(最佳實務)
新增檔案:
/VenderPortal/PurchaseOrders/PurchaseOrderConsts.Extensions.cs
寫入:
namespace VenderPortal.PurchaseOrders
{
public static partial class PurchaseOrderConsts
{
public const string PlantChongqing = "重慶";
public const string PlantKunshan = "昆山";
public static readonly HashSet<string> ValidPlants = new HashSet<string>
{
PlantChongqing,
PlantKunshan,
};
}
}
優點
✅ 永不被 ABP Suite 覆寫
✅ 不修改 Suite 的自動產生邏輯
✅ 適合放 domain rule、固定字串、固定清單
✅ 維持清楚的分層(產生 vs 自定義)
Suite 模板修改後實際生成結果
ABP Suite 生成
public static partial class PurchaseOrderConsts
{
private const string DefaultSorting = "{0}CreationTime desc";
public static string GetDefaultSorting(bool withEntityName)
{
return string.Format(DefaultSorting, withEntityName ? "PurchaseOrder." : string.Empty);
}
public const int PoNoMaxLength = 50;
public const int WorkOrderMaxLength = 50;
public const int PoPnMaxLength = 50;
// ...
}
你的擴充
public static partial class PurchaseOrderConsts
{
public const string PlantChongqing = "重慶";
public const string PlantKunshan = "昆山";
public static readonly HashSet<string> ValidPlants = new HashSet<string>
{
PlantChongqing,
PlantKunshan,
};
}
延伸用法
在 DTO 驗證中引用常數
[Required]
[MaxLength(PurchaseOrderConsts.PlantMaxLength)]
[AllowedValues(PurchaseOrderConsts.ValidPlants)]
public string Plant { get; set; }
在 Domain Layer 使用
if (!PurchaseOrderConsts.ValidPlants.Contains(plant))
{
throw new BusinessException("InvalidPlant").WithData("Plant", plant);
}
在 AppService 中做 mapping 或 filter
var validItems = query.Where(po =>
PurchaseOrderConsts.ValidPlants.Contains(po.Plant)
);
注意事項
結論
使用:
修改模板 →
partial class自訂常數放到外部 partial 檔案
是目前 ABP Suite 最穩定、不會被覆寫、可維護性最高的做法。
26 November 2025