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);
}
}
}