CustomCache - ScutGame/Scut GitHub Wiki

此章节介绍如何使用服务端的自定义Cache缓存

自定义缓存模型

Scut提供了MemoryCacheStruct类处理自定的缓存模型。

自定义实体

通过继承MemoryEntity基类,扩展自己的实体对象,需要重载GetKeyCode方法指定对象的主键值;此实体也会自己创建数据库表的。

自定义数据加载

通过继承MemoryCacheStruct类,重载InitCache方法,处理自己需要的加载逻辑;此类并提供了从DB或Redis库加载数据的TryLoadFromDb和TryLoadFromRedis方法,需要自定实现将数据反序列化为实体对象,可以重载SetPropertyValue方法。

自定义更新机制

通过继承MemoryCacheStruct类,可定义方法调用它提供的TrySaveToDb和TrySaveToRedis方法,将实体对象更新到Db和Redis库;需要自定实现将实体对象序列化可以重载GetPropertyValue方法。

订单示例

实现步骤

(1) 定义实体:实现定义中Index属性表示需要创建的索引字段(多个字段用','号分隔),IsUnique是指定字段为唯一约束;

    /// <summary>
    /// 充值订单
    /// </summary>
    [EntityTable(CacheType.None, DbCofingKeys.DataKey, StorageType = StorageType.ReadWriteDB, Indexs = new[] { "UserID" })]
    public class PayOrder : MemoryEntity
    {
        /// <summary>
        /// 自增编号,主键
        /// </summary>
        [EntityField(true, IsIdentity = true)]
        public long ID { get; set; }

        /// <summary>
        /// 订单号
        /// </summary>
        [EntityField(IsUnique = true, Isnullable = false)]
        public string OrderNo { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [EntityField(Isnullable = false)]
        public int UserID { get; set; }

        /// <summary>
        /// 游戏代币
        /// </summary>
        [EntityField(Isnullable = false)]
        public int Memory { get; set; }

        /// <summary>
        /// 是否已领取
        /// </summary>
        [EntityField]
        public bool IsReceived { get; set; }

        /// <summary>
        /// 下单时间
        /// </summary>
        [EntityField(Isnullable = false)]
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 领取时间
        /// </summary>
        [EntityField]
        public DateTime ReceiveTime { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string GetKeyCode()
        {
            return ID.ToString();
        }

(2) 定义缓存结构

    /// <summary>
    /// 充值订单模块
    /// </summary>
    public class PayOrderModule : MemoryCacheStruct<PayOrder>
    {
        /// <summary>
        /// 刷新新订单
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public bool Refresh(int userId)
        {
            return InitUserCache(userId);
        }

        /// <summary>
        /// 接收成功
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool ReceiveSuccess(PayOrder data)
        {
            if (TryRemove(data.ID.ToString()))
            {
                data.ModifyLocked(() =>
                {
                    data.IsReceived = true;
                    data.ReceiveTime = DateTime.Now;
                });
                return TrySaveToDb(new[] { data }, true); //第二个参数true表示同步更新
            }
            return false;
        }

        protected bool InitUserCache(int userId)
        {
            var filter = new DbDataFilter();
            filter.Parameters = new Parameters();
            if (userId > 0)
            {
                filter.Condition = "IsReceived = @IsReceived AND UserID = @UserID";
                filter.Parameters.Add("@UserID", userId);
            }
            else
            {
                filter.Condition = "IsReceived = @IsReceived";
            }
            filter.Parameters.Add("@IsReceived", false);
            List<PayOrder> dataList;
            if (TryLoadFromDb(filter, out dataList))
            {
                foreach (var payOrder in dataList)
                {
                    PayOrder data;
                    if (!TryGet(payOrder.ID.ToString(), out data))
                    {
                        TryAdd(payOrder.ID.ToString(), payOrder);
                    }
                }
                return true;
            }
            return false;
        }

        protected override bool InitCache()
        {
            return InitUserCache(0);
        }

    }

(3) 调用代码

private void PayOrderCheck()
{
    PayOrderModule orderModule = new PayOrderModule();
    var list = orderModule.FindAll();
    foreach (var payOrder in list)
    {
        var userRole = PersonalCacheStruct.Get<UserRole>(payOrder.UserID.ToString(), false, payOrder.UserID);
        if (orderModule.ReceiveSuccess(payOrder))
        {
            var roleModule = new RoleModule(userRole);
            roleModule.AddMoney((uint)payOrder.Memory);
        }

    }
}
⚠️ **GitHub.com Fallback** ⚠️