Redis не удаляет записи из базы данных - PullRequest
1 голос
/ 10 ноября 2019

Прежде всего, я использую эту обертку: https://github.com/garywoodfine/redis-mvc-core/blob/master/RedisConfiguration/RedisVoteService.cs и Delete(...), похоже, не работают. Я думаю, что пытался IDistributedCache, и раньше он также не удалял объект, но он по крайней мере null'd все свойства.

Вы можете увидеть в комментариях, что я пытался FlushDatabase(), но это не таккажется, тоже работает. Я хочу, чтобы метод Delete, чтобы удалить объекты. Не только обнулить их (это тоже не работает).

Есть идеи? Честно говоря, я хотел бы получить лучшую обертку, которая поддерживает List<T>.

enter image description here

var redis = new RedisAlgorithmService<BotSession>(_connectionFactory);
var test = redis.Get("Test");
if (test == null)
    redis.Save("Test", new BotSession(TrendType.Uptrend, bot.Id));
test.NTimes = 123;
redis.Delete("Test");
using StackExchange.Redis;
using System;

namespace Binance.Redis
{
    public class RedisAlgorithmService<T> : BaseService<T>, IRedisService<T>
    {
        internal readonly IRedisConnectionFactory _connectionFactory;
        protected readonly IDatabase _database;

        public RedisAlgorithmService(IRedisConnectionFactory connectionFactory)
        {
            _connectionFactory = connectionFactory;
            _database = _connectionFactory.Connection().GetDatabase();
        }

        public void Delete(string key)
        {
            if (string.IsNullOrWhiteSpace(key) || key.Contains(":")) 
                throw new ArgumentException("Invalid key!");

            key = GenerateKey(key);
            _database.KeyDelete(key);

            // _database.HashDelete(key, );

            // var endpoints = _connectionFactory.Connection().GetEndPoints();
            // _connectionFactory.Connection().GetServer(endpoints[0]).FlushDatabase();
        }

        public T Get(string key)
        {
            key = GenerateKey(key);
            var hash = _database.HashGetAll(key);
            return MapFromHash(hash);
        }

        public void Save(string key, T obj)
        {
            if (obj != null)
            {
                var hash = GenerateHash(obj);
                key = GenerateKey(key);

                if (_database.HashLength(key) == 0)
                {
                    _database.HashSet(key, hash);
                }
                else
                {
                    var props = Properties;
                    foreach (var item in props)
                    {
                        if (_database.HashExists(key, item.Name))
                        {
                            _database.HashIncrement(key, item.Name, Convert.ToInt32(item.GetValue(obj)));
                        }
                    }
                }

            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 11 ноября 2019

Не уверен, что FlushDatabase() или FlushAllDatabase() - это именно то, что вам нужно:

  • FLUSHDB - удаляет все ключи из текущей базы данных соединения.
  • FLUSHALL - удаляет все ключииз всех баз данных.

Существует другой обходной путь, использующий методы расширения и Newtonsoft.Json в качестве сериализатора / десериализатора. Я понимаю, что IDistributedCache поддерживает только строковый / байтовый массив в качестве входных данных, и вы не можете передать ему объекты класса, и этот обходной путь поможет вам сделать это.

Startup.cs

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "name";
});

CacheExtensions.cs

namespace TestProject.Extensions
{
    public static class CacheExtensions
    {
        public static async Task<T> SetAsync<T>(this IDistributedCache cache, string key, T item)
        {
            var json = JsonConvert.SerializeObject(item);

            await cache.SetStringAsync(key, json);

            return await cache.GetAsync<T>(key);
        }

        public static async Task<T> SetAsync<T>(this IDistributedCache cache, string key, T item, int expirationInHours)
        {
            var json = JsonConvert.SerializeObject(item);

            await cache.SetStringAsync(key, json, new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(expirationInHours)
            });

            return await cache.GetAsync<T>(key);
        }

        public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key)
        {
            var json = await cache.GetStringAsync(key);

            if (json == null)
                return default;

            return JsonConvert.DeserializeObject<T>(json);
        }
    }
}

DI IDistributedCache:

private readonly IDistributedCache _cache;

public TestService(IDistributedCache cache)
{
    _cache = cache;
}

и используйте его так:

List<Test> testList = new List<Test>
{
    new Test(...),
    new Test(...)
};

var test = await _cache.GetAsync<List<Test>>("ListKey");
await _cache.SetAsync("ListKey", testList);
await _cache.RemoveAsync("ListKey");

var test2 = await _cache.GetAsync<Test>("key");
await _cache.SetAsync("key", new Test(...));
await _cache.RemoveAsync("key");

Надеюсь, это поможет.

0 голосов
/ 11 ноября 2019

Я не уверен, поможет ли это вам. Я видел этот метод, который вы пробовали, но он кажется неполным.

Попробуйте также удалить хеш.

DeleteHash(string key, string cacheSubKey)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("Some problem here !");

            _database.HashDelete(key, cacheSubKey);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...