public override async Task <ScreamResult> RemoveAsync(int screamId)
        {
            if (!Scream.IsValidId(screamId))
            {
                throw new NullReferenceException("invalid scream Id");
            }

            var scream = await DB.Screams.AsNoTracking().Where(s => s.Id == screamId).SingleOrDefaultAsync();

            var comments = await DB.Comments.AsNoTracking().Where(c => c.ScreamId == screamId).ToListAsync();

            DB.Comments.RemoveRange(comments);
            if (scream == null)
            {
                throw new NullReferenceException("scream not exist");
            }
            DB.Screams.Remove(scream);

            int effects = await DB.SaveChangesAsync();

            if (effects == comments.Count + 1)
            {
                await _redis.KeyDeleteAsync(Scream.GetCacheKey(screamId));

                return(QuickResult.Successful());
            }
            return(QuickResult.Unsuccessful("Delete scream fail"));
        }
        /// <summary>
        /// get the subject of scream
        /// </summary>
        /// <param name="screamId"></param>
        /// <returns></returns>
        public override async Task <Scream> GetScreamAsync(int screamId)
        {
            if (!Scream.IsValidId(screamId))
            {
                return(null);
            }

            string redisValue;
            string currentKey = Scream.GetCacheKey(screamId);
            Scream result     = null;

            if (await _redis.KeyExistsAsync(currentKey))
            {
                redisValue = await _redis.StringGetAsync(currentKey);

                result = new Scream(
                    JsonConvert.DeserializeObject <ScreamBackend.DB.Tables.Scream>(redisValue),
                    this
                    );
            }
            else
            {
                var model = await DB.Screams.AsNoTracking().SingleOrDefaultAsync(s => s.Id == screamId);

                if (model == null)
                {
                    return(null);
                }
                result     = new Scream(model, this);
                redisValue = JsonConvert.SerializeObject(result.Model);
                await _redis.StringSetAsync(key : currentKey, redisValue);
            }
            await _redis.KeyExpireAsync(currentKey, TimeSpan.FromHours(1));

            return(result);
        }