You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据库更新后重载父ReadOnlyBase对象中的子BusinessListBase对象

强制刷新CSLA只读对象子对象的实现方案

1. 核心思路

你的只读对象(A、B)是内存缓存的,当外部微服务直接修改数据库中C的数据后,可通过缓存失效+重新加载或局部刷新子对象两种方式同步数据,结合已有的通知服务,在收到变更通知时执行对应逻辑即可。

2. 方案一:全量清除缓存,下次请求自动加载最新数据

CSLA的ReadOnlyBase默认支持数据门户缓存,你可以通过DataPortal.ClearCache方法清除指定对象的缓存,下次请求该对象时,会重新从数据库拉取包含最新C数据的完整对象。

实现代码

// 通知服务的消息处理方法
public void HandleDatabaseChange(int targetAId)
{
    // 清除A对象的缓存,参数为对象类型和Fetch时用的标识(比如A的ID)
    Csla.DataPortal.ClearCache(typeof(A), new object[] { targetAId });
    
    // 如果只需要刷新特定B对象,可单独清除B的缓存
    // Csla.DataPortal.ClearCache(typeof(B), new object[] { targetBId });
}

这种方式简单直接,无需修改原有业务类,适合不需要实时刷新、允许下次请求同步数据的场景。

3. 方案二:局部刷新子对象(实时更新缓存中的对象)

如果需要实时更新缓存中的对象,不用等下次请求,可以在只读对象中添加内部刷新方法,直接更新子对象集合。

修改业务类代码

// 修改B类,添加刷新CList的方法
public class B : ReadOnlyBase<B>
{
    public int Id { get; private set; }
    public CList Cs { get; private set; }

    // 原有数据加载逻辑
    private void DataPortal_Fetch(int id)
    {
        Id = id;
        // 从数据库加载对应CList
        Cs = DataPortal.Fetch<CList>(id);
    }

    // 内部刷新方法,供通知处理逻辑调用
    internal void RefreshCs()
    {
        // 重新从数据库拉取最新的CList并替换原有属性
        Cs = DataPortal.Fetch<CList>(Id);
        // 触发属性变更通知(适配UI绑定或属性监听场景)
        PropertyHasChanged(nameof(Cs));
    }
}

// CList的加载逻辑补充
public class CList : BusinessListBase<CList, C>
{
    private void DataPortal_Fetch(int bId)
    {
        // 从数据库查询属于当前B的所有C数据
        using (var db = new YourDbContext())
        {
            var cDataList = db.Cs.Where(c => c.BId == bId).ToList();
            foreach (var c in cDataList)
            {
                Add(c);
            }
        }
    }
}

通知处理逻辑

public class DatabaseChangeNotificationHandler
{
    // 假设通知消息包含关联的B的ID
    public void HandleCChanged(int relatedBId)
    {
        // 从缓存中获取已加载的B对象(自定义内存缓存需自行实现获取逻辑)
        var cachedB = Csla.ApplicationContext.LocalContext.Get<B>($"B_{relatedBId}");
        
        if (cachedB != null)
        {
            // 加锁保证线程安全,避免并发修改缓存对象
            lock (cachedB)
            {
                cachedB.RefreshCs();
            }
        }
        // 同时清除缓存,防止后续请求拿到旧数据
        Csla.DataPortal.ClearCache(typeof(B), new object[] { relatedBId });
    }
}

4. 注意事项

  • 线程安全:缓存对象可能被多个请求同时访问,刷新时必须加锁,避免并发修改导致的数据异常
  • 缓存策略一致性:确保CSLA的缓存配置(如缓存键、过期时间)和通知触发的失效逻辑对齐,避免出现缓存不一致
  • 只读对象设计规范:CSLA只读对象建议保持不可变性,局部刷新时应直接替换子对象(如CList),不要修改子对象内部的属性值

内容的提问来源于stack exchange,提问作者user1890098

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:33:28