예제 #1
0
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="dataRetriever">数据检索器</param>
        /// <param name="expiration">过期时间</param>
        /// <returns></returns>
        public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) where T : class
        {
            cacheKey.CheckNotNullOrEmpty(nameof(cacheKey));
            expiration.CheckGreaterThan(nameof(expiration), TimeSpan.Zero);

            var tempCacheKey = AddSysCustomKey(cacheKey);

            var result = _database.StringGet(tempCacheKey);

            if (!result.IsNull)
            {
                //var value = ToObj<T>(result);
                var value = _serializer.Deserialize <T>(result);
                return(new CacheValue <T>(value, true));
            }

            var item = dataRetriever?.Invoke();

            if (item != null)
            {
                Set(cacheKey, item, expiration);
                return(new CacheValue <T>(item, true));
            }
            return(CacheValue <T> .NoValue);
        }
예제 #2
0
        private object Deserialize(RedisValue value, string valueType)
        {
            var type = TypeCache.GetType(valueType);

            EnsureNotNull(type, "Type could not be loaded, {0}.", valueType);

            return(_serializer.Deserialize(value, type));
        }
예제 #3
0
 public void RollBack()
 {
     foreach (var kv in m_Entities)
     {
         ISqlEntity dumpedEntity = m_Serializer.Deserialize(kv.Value, kv.Key.GetType()) as ISqlEntity;
         foreach (var prop in kv.Key.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
         {
             prop.SetValue(kv.Key, prop.GetValue(dumpedEntity));
         }
     }
 }
예제 #4
0
        public async Task <CacheResult <Products> > GetAsync(int id)
        {
            var cacheResult = await _context.Database.StringGetAsync($"products.{id}");

            if (!cacheResult.HasValue)
            {
                return(CacheResult <Products> .NoData());
            }

            var product = _cacheResializer.Deserialize <Products>(cacheResult);

            return(CacheResult <Products> .Result(product));
        }
예제 #5
0
        public Task <T> GetAsync <T>(string key)
        {
            return(Task.Run(async() =>
            {
                var value = await GetAsync(key);

                if (value == null)
                {
                    return default(T);
                }

                var result = Serializer.Deserialize <T>(value);
                return result;
            }));
        }
예제 #6
0
 private CacheEntry <T> TryGetCacheResult(byte[] cacheResult)
 {
     if (cacheResult == default || cacheResult.Length <= 0)
     {
         return(CacheEntry <T> .NotFound);
     }
     try
     {
         var entityCache = _cacheSerializer.Deserialize <T>(cacheResult);
         return(CacheEntry <T> .Create(true, entityCache));
     }
     catch
     {
         return(CacheEntry <T> .NotFound);
     }
 }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="cacheKey">缓存类型</param>
        /// <returns></returns>
        public CacheValue <T> Get <T>(string cacheKey)
        {
            Check.NotNullOrEmpty(cacheKey, nameof(cacheKey));

            var result = _cache.StringGet(cacheKey);

            if (!result.IsNull)
            {
                WriteLog($"缓存击中 : cacheKey = {cacheKey}");
                CacheStatsInfo.OnHit();
                var value = _serializer.Deserialize <T>(result);
                return(new CacheValue <T>(value, true));
            }

            CacheStatsInfo.OnMiss();
            WriteLog($"缓存穿透 : cacheKey = {cacheKey}");

            return(CacheValue <T> .NoValue);
        }
예제 #8
0
        /// <summary>
        /// 通过Redis键获取实体对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="isRemove"></param>
        /// <param name="type"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public static dynamic GetEntityFromRedis(string key, bool isRemove, Type type, ICacheSerializer serializer)
        {
            string  typeName;
            string  asmName;
            bool    isEntityType;
            string  redisKey;
            string  entityKey = GetEntityTypeFromKey(key, out typeName, ref type, out asmName, out isEntityType, out redisKey);
            dynamic entity    = null;

            RedisConnectionPool.Process(client =>
            {
                if (isEntityType)
                {
                    var data = client.Get <byte[]>(redisKey);
                    if (data != null && type != null)
                    {
                        entity = serializer.Deserialize(data, type);
                    }
                }
                else
                {
                    var data = client.Get <byte[]>(redisKey);
                    if (data != null && type != null)
                    {
                        var dict = (IDictionary)serializer.Deserialize(data, type);
                        entity   = dict[entityKey];
                    }
                }
                if (entity == null)
                {
                    //新版本Hash格式
                    var data = client.HGet(typeName, RedisConnectionPool.ToByteKey(entityKey));
                    if (data != null && type != null)
                    {
                        entity = serializer.Deserialize(data, type);
                    }
                }

                if (isRemove && entity == null && type != null)
                {
                    //临时队列删除Entity
                    string setId     = (isEntityType ? RedisConnectionPool.EncodeTypeName(typeName) : redisKey) + ":remove";
                    IDictionary dict = null;
                    RedisConnectionPool.ProcessTrans(client, new string[] { setId }, () =>
                    {
                        var data = client.Get <byte[]>(setId);
                        if (data == null)
                        {
                            return(false);
                        }
                        dict   = (IDictionary)serializer.Deserialize(data, type);
                        entity = dict[entityKey];
                        dict.Remove(entityKey);

                        return(true);
                    }, trans =>
                    {
                        if (dict != null && dict.Count > 0)
                        {
                            trans.QueueCommand(c => c.Set(setId, serializer.Serialize(dict)));
                        }
                        else
                        {
                            trans.QueueCommand(c => c.Remove(setId));
                        }
                    }, null);
                }
            });
            return(entity);
        }
예제 #9
0
        /// <summary>
        /// 从历史库中加载数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public bool TryLoadHistory <T>(string redisKey, out List <T> dataList) where T : ISqlEntity
        {
            string[] entityAndKeys = (redisKey ?? "").Split('_');
            var      entityKey     = entityAndKeys.Length > 1 ? entityAndKeys[1] : null;
            string   entityNameKey = RedisConnectionPool.GetRedisEntityKeyName(entityAndKeys[0]);

            bool result = false;

            dataList = null;
            SchemaTable schemaTable;

            if (EntitySchemaSet.TryGet <EntityHistory>(out schemaTable))
            {
                try
                {
                    var provider = DbConnectionProvider.CreateDbProvider(schemaTable);
                    if (provider == null)
                    {
                        //DB is optional and can no DB configuration
                        dataList = new List <T>();
                        return(true);
                    }
                    TransReceiveParam receiveParam = new TransReceiveParam(entityNameKey);
                    receiveParam.Schema = schemaTable;
                    int    maxCount     = receiveParam.Schema.Capacity;
                    var    filter       = new DbDataFilter(maxCount);
                    string key          = schemaTable.Keys[0];
                    var    entitySchema = EntitySchemaSet.Get(entityAndKeys[0]);

                    if (entitySchema != null && entitySchema.Keys.Length == 1)
                    {
                        filter.Condition = provider.FormatFilterParam(key);
                        filter.Parameters.Add(key, string.Format("{0}_{1}", entityNameKey, entityKey));
                    }
                    else
                    {
                        filter.Condition = provider.FormatFilterParam(key, "LIKE");
                        filter.Parameters.Add(key, string.Format("{0}_%{1}%", entityNameKey, entityKey));
                    }
                    receiveParam.DbFilter = filter;

                    List <EntityHistory> historyList;
                    if (_dbTransponder.TryReceiveData(receiveParam, out historyList))
                    {
                        if (historyList.Count == 0)
                        {
                            dataList = new List <T>();
                            return(true);
                        }
                        dataList = new List <T>();
                        var keyBytes   = new byte[historyList.Count][];
                        var valueBytes = new byte[historyList.Count][];
                        for (int i = 0; i < keyBytes.Length; i++)
                        {
                            var entityHistory = historyList[i];
                            keyBytes[i]   = RedisConnectionPool.ToByteKey(entityHistory.Key.Split('_')[1]);
                            valueBytes[i] = entityHistory.Value;
                            dataList.Add((T)_serializer.Deserialize(entityHistory.Value, typeof(T)));
                        }
                        //从DB备份中恢复到Redis, 多个Key时也要更新
                        var entitys = dataList.ToArray();
                        RedisConnectionPool.Process(client =>
                        {
                            client.HMSet(entityNameKey, keyBytes, valueBytes);
                            if (entitySchema.Keys.Length > 1)
                            {
                                RedisConnectionPool.UpdateFromMutilKeyMap <T>(client, entityKey, entitys);
                            }
                        });
                        result = true;
                    }
                }
                catch (Exception ex)
                {
                    TraceLog.WriteError("Try load Redis's history key:{0}\r\nerror:{1}", entityNameKey, ex);
                }
            }
            else
            {
                dataList = new List <T>();
                result   = true;
            }
            return(result);
        }
예제 #10
0
        /// <summary>
        /// Try get entity
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="table"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TryGetEntity <T>(string redisKey, SchemaTable table, out List <T> list) where T : AbstractEntity
        {
            list = new List <T>();
            bool result = false;

            try
            {
                //修改存储统一Hash格式(TypeName, keyCode, value)
                var    keys     = redisKey.Split('_');
                string keyValue = "";
                string hashId   = GetRedisEntityKeyName(keys[0]);
                byte[] keyCode  = null;
                if (keys.Length > 1)
                {
                    keyValue = keys[1];
                    keyCode  = ToByteKey(keyValue);
                }
                byte[][] valueBytes = null;
                byte[]   value      = null;
                bool     isFilter   = false;
                try
                {
                    ProcessReadOnly(client =>
                    {
                        if (keyCode == null)
                        {
                            if (client.ContainsKey(hashId))
                            {
                                valueBytes = client.HVals(hashId);//.Where((b, index) => index % 2 == 1).ToArray();
                            }
                        }
                        else
                        {
                            value = client.HGet(hashId, keyCode);
                            //修正未使用Persional作为Key,而是多个Key时,加载数据为空问题,修改成加载所有
                            if (value == null && table != null &&
                                !string.IsNullOrEmpty(keyValue) &&
                                typeof(T).IsSubclassOf(typeof(BaseEntity)) &&
                                table.Keys.Length > 1)
                            {
                                isFilter            = true;
                                byte[][] resultKeys = client.HKeys(hashId).Where(k => ContainKey(k, keyCode, AbstractEntity.KeyCodeJoinChar)).ToArray();
                                if (resultKeys.Length > 0)
                                {
                                    valueBytes = client.HMGet(hashId, resultKeys);//.Where((b, index) => index % 2 == 1).ToArray();
                                }
                            }
                        }
                    });

                    if (valueBytes != null || value != null)
                    {
                        if (value != null)
                        {
                            list = new List <T> {
                                (T)_serializer.Deserialize(value, typeof(T))
                            };
                            return(true);
                        }
                        if (valueBytes != null)
                        {
                            if (isFilter)
                            {
                                list = valueBytes.Select(t => (T)_serializer.Deserialize(t, typeof(T))).Where(t => t.PersonalId == keyValue).ToList();
                            }
                            else
                            {
                                list = valueBytes.Select(t => (T)_serializer.Deserialize(t, typeof(T))).ToList();
                            }
                            return(true);
                        }
                    }
                }
                catch (Exception er)
                {
                    list = null;
                    TraceLog.WriteError("Get redis \"{0}\" key:\"{1}\" cache error:{2}", typeof(T).FullName, redisKey, er);
                }

                try
                {
                    //从旧版本存储格式中查找
                    if (typeof(T).IsSubclassOf(typeof(ShareEntity)))
                    {
                        byte[][]      buffers = new byte[0][];
                        List <string> keyList = new List <string>();
                        ProcessReadOnly(client =>
                        {
                            keyList = client.SearchKeys(string.Format("{0}_*", redisKey));
                            if (keyList != null && keyList.Count > 0)
                            {
                                buffers = client.MGet(keyList.ToArray());
                            }
                        });
                        list = new List <T>();
                        byte[][] keyCodes = new byte[buffers.Length][];
                        for (int i = 0; i < buffers.Length; i++)
                        {
                            T entity = (T)_serializer.Deserialize(buffers[i], typeof(T));
                            keyCodes[i] = ToByteKey(entity.GetKeyCode());
                            list.Add(entity);
                        }
                        if (keyCodes.Length > 0)
                        {
                            //转移到新格式
                            UpdateEntity(typeof(T).FullName, keyCodes, buffers);
                            if (keyList.Count > 0)
                            {
                                Process(client => client.RemoveAll(keyList));
                            }
                        }
                    }
                    else
                    {
                        byte[] buffers = new byte[0];
                        ProcessReadOnly(client =>
                        {
                            buffers = client.Get <byte[]>(redisKey) ?? new byte[0];
                        });

                        try
                        {
                            var dataSet = (Dictionary <string, T>)_serializer.Deserialize(buffers, typeof(Dictionary <string, T>));
                            if (dataSet != null)
                            {
                                list = dataSet.Values.ToList();
                            }
                        }
                        catch
                        {
                            //try get entity type data
                            list = new List <T>();
                            T temp = (T)_serializer.Deserialize(buffers, typeof(T));
                            list.Add(temp);
                        }
                        //转移到新格式
                        if (list != null)
                        {
                            byte[][] keyCodes = new byte[list.Count][];
                            byte[][] values   = new byte[list.Count][];
                            for (int i = 0; i < list.Count; i++)
                            {
                                T entity = list[i];
                                keyCodes[i] = ToByteKey(entity.GetKeyCode());
                                values[i]   = _serializer.Serialize(entity);
                            }
                            if (keyCodes.Length > 0)
                            {
                                UpdateEntity(typeof(T).FullName, keyCodes, values);
                                Process(client => client.Remove(redisKey));
                            }
                        }
                    }
                    result = true;
                }
                catch (Exception er)
                {
                    list = null;
                    TraceLog.WriteError("Get redis \"{0}\" key(old):\"{1}\" cache error:{2}", typeof(T).FullName, redisKey, er);
                }
            }
            catch (Exception ex)
            {
                list = null;
                TraceLog.WriteError("Get redis \"{0}\" key:\"{1}\" cache error:{2}", typeof(T).FullName, redisKey, ex);
            }
            return(result);
        }
예제 #11
0
        public async Task <T> GetAsync <T>(string key)
        {
            var result = await GetAsync(key);

            return(Serializer.Deserialize <T>(result));
        }
예제 #12
0
        /// <summary>
        /// 从历史库中加载数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public bool TryLoadHistory <T>(string redisKey, out List <T> dataList)
        {
            string entityNameKey = RedisConnectionPool.GetRedisEntityKeyName(redisKey);
            bool   result        = false;

            dataList = null;
            SchemaTable schemaTable;

            if (EntitySchemaSet.TryGet <EntityHistory>(out schemaTable))
            {
                try
                {
                    var provider = DbConnectionProvider.CreateDbProvider(schemaTable);
                    if (provider == null)
                    {
                        //DB is optional and can no DB configuration
                        dataList = new List <T>();
                        return(true);
                    }
                    TransReceiveParam receiveParam = new TransReceiveParam(entityNameKey);
                    receiveParam.Schema = schemaTable;
                    int    maxCount = receiveParam.Schema.Capacity;
                    var    filter   = new DbDataFilter(maxCount);
                    string key      = schemaTable.Keys[0];
                    filter.Condition = provider.FormatFilterParam(key);
                    filter.Parameters.Add(key, entityNameKey);
                    receiveParam.DbFilter = filter;
                    receiveParam.Capacity = maxCount;

                    List <EntityHistory> historyList;
                    if (_dbTransponder.TryReceiveData(receiveParam, out historyList))
                    {
                        EntityHistory history = historyList.Count > 0 ? historyList[0] : null;
                        if (history != null && history.Value != null && history.Value.Length > 0)
                        {
                            //从DB备份中取使用protobuf
                            byte[][] bufferBytes = ProtoBufUtils.Deserialize <byte[][]>(history.Value);
                            byte[][] keys        = bufferBytes.Where((b, index) => index % 2 == 0).ToArray();
                            byte[][] values      = bufferBytes.Where((b, index) => index % 2 == 1).ToArray();
                            RedisConnectionPool.Process(client => client.HMSet(entityNameKey, keys, values));
                            dataList = values.Select(value => (T)_serializer.Deserialize(value, typeof(T))).ToList();
                            result   = true;
                        }
                        else
                        {
                            dataList = new List <T>();
                            result   = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    TraceLog.WriteError("Try load Redis's history key:{0}\r\nerror:{1}", entityNameKey, ex);
                }
            }
            else
            {
                dataList = new List <T>();
                result   = true;
            }
            return(result);
        }
예제 #13
0
        /// <summary>
        /// Try get entity
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redisKey"></param>
        /// <param name="table"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TryGetEntity <T>(string redisKey, SchemaTable table, out List <T> list) where T : ISqlEntity
        {
            bool result = false;

            try
            {
                //修改存储统一Hash格式(TypeName, keyCode, value)
                var    keys     = redisKey.Split('_');
                string keyValue = "";
                string hashId   = GetRedisEntityKeyName(keys[0]);
                byte[] keyCode  = null;
                if (keys.Length > 1)
                {
                    keyValue = keys[1];
                    keyCode  = ToByteKey(keyValue);
                }
                byte[][] valueBytes = null;
                byte[]   value      = null;
                bool     isFilter   = false;
                try
                {
                    ProcessReadOnly(client =>
                    {
                        if (keyCode == null)
                        {
                            if (client.ContainsKey(hashId))
                            {
                                valueBytes = client.HVals(hashId);//.Where((b, index) => index % 2 == 1).ToArray();
                            }
                        }
                        else
                        {
                            value = client.HGet(hashId, keyCode);
                            //修正未使用Persional作为Key,而是多个Key时,加载数据为空问题,修改成加载所有
                            if (value == null && table != null &&
                                !string.IsNullOrEmpty(keyValue) &&
                                typeof(T).IsSubclassOf(typeof(BaseEntity)) &&
                                table.Keys.Length > 1)
                            {
                                isFilter            = true;
                                byte[][] resultKeys = client.HKeys(hashId).Where(k => ContainKey(k, keyCode, AbstractEntity.KeyCodeJoinChar)).ToArray();
                                if (resultKeys.Length > 0)
                                {
                                    valueBytes = client.HMGet(hashId, resultKeys);//.Where((b, index) => index % 2 == 1).ToArray();
                                }
                            }
                        }
                    });

                    if (valueBytes != null || value != null)
                    {
                        if (value != null)
                        {
                            list = new List <T> {
                                (T)_serializer.Deserialize(value, typeof(T))
                            };
                            return(true);
                        }
                        if (valueBytes != null)
                        {
                            if (isFilter)
                            {
                                list = valueBytes.Select(t => (T)_serializer.Deserialize(t, typeof(T))).Where(t => t.PersonalId == keyValue).ToList();
                            }
                            else
                            {
                                list = valueBytes.Select(t => (T)_serializer.Deserialize(t, typeof(T))).ToList();
                            }
                            return(true);
                        }
                    }
                }
                catch (Exception er)
                {
                    TraceLog.WriteError("Get redis \"{0}\" key:\"{1}\" cache error:{2}", typeof(T).FullName, redisKey, er);
                }

                result = TryGetOlbValue(redisKey, out list);
            }
            catch (Exception ex)
            {
                list = null;
                TraceLog.WriteError("Get redis \"{0}\" key:\"{1}\" cache error:{2}", typeof(T).FullName, redisKey, ex);
            }
            return(result);
        }