如何让DevExpress XPO子类OrderDetails表拥有modified_at物理字段?
在DevExpress XPO中为PostgreSQL子类表添加独立modified_at字段并自动更新
针对你遇到的问题,这里有两种简便的实现方案,不用复杂修改继承逻辑:
方案一:调整XPO继承映射为「每个类一张表」
XPO默认的Joined继承(父表存基类字段、子表存子类特有字段)会导致基类的modified_at只存在于父表。改成**Table-Per-Class(每个类对应独立表)**后,子类表会包含基类的所有字段,包括modified_at,同时保留自动更新逻辑。
步骤:
- 在基类
OrderBase上添加继承映射特性:[MapInheritance(MapInheritanceType.OwnTable)] public class OrderBase : XPObject { // 已有的modified_at字段及自动更新逻辑 private DateTime _modified_at; [Persistent, DbType("TIMESTAMP WITH TIME ZONE")] public DateTime modified_at { get { return _modified_at; } set { SetPropertyValue(nameof(modified_at), ref _modified_at, value); } } protected override void OnSaving() { base.OnSaving(); modified_at = DateTime.UtcNow; // 保存时自动更新 } // 其他基类属性... } - 子类
OrderDetails无需额外添加字段,直接继承即可:public class OrderDetails : OrderBase { // 子类特有属性... } - 更新数据库架构:调用
Session.UpdateSchema(typeof(OrderBase), typeof(OrderDetails)),或用DevExpress的Schema Migration工具自动生成OrderDetails表的modified_at字段。
方案二:用PostgreSQL触发器实现子类表字段自动更新
如果不想修改现有继承结构,直接通过数据库触发器给OrderDetails表添加字段并自动更新,XPO只需要映射该字段即可。
步骤:
- 给PostgreSQL的
OrderDetails表添加字段:ALTER TABLE OrderDetails ADD COLUMN modified_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP; - 创建触发器函数:
CREATE OR REPLACE FUNCTION update_modified_at() RETURNS TRIGGER AS $$ BEGIN NEW.modified_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; - 绑定触发器到
OrderDetails表:CREATE TRIGGER trigger_orderdetails_modified_at BEFORE UPDATE ON OrderDetails FOR EACH ROW EXECUTE FUNCTION update_modified_at(); - 在
OrderDetails类中添加对应映射属性(标记为只读,避免XPO和触发器冲突):public class OrderDetails : OrderBase { private DateTime _modified_at; [Persistent, DbType("TIMESTAMP WITH TIME ZONE"), ReadOnly(true)] public DateTime modified_at { get { return _modified_at; } set { SetPropertyValue(nameof(modified_at), ref _modified_at, value); } } // 子类特有属性... }
方案对比
- 方案一:XPO统一管理字段和更新逻辑,适合后续有多个子类需要该字段的场景,架构更统一。
- 方案二:利用数据库原生能力,无需修改继承结构,灵活度高,适合仅给特定子类添加字段的场景。
内容的提问来源于stack exchange,提问作者Stavros Koureas
相关产品推荐
相关产品推荐

