/// <summary>
        /// Sets the specified value to a hashset using the pair hashKey+field.
        /// (The latest expiration applies to the whole key)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">The key.</param>
        /// <param name="field">The field key</param>
        /// <param name="value">The value to store</param>
        /// <param name="tags">The tags to relate to this field.</param>
        /// <param name="ttl">Set the current expiration timespan to the whole key (not only this hash). NULL to keep the current expiration.</param>
        /// <param name="when">Indicates when this operation should be performed.</param>
        public void SetHashed <T>(string key, string field, T value, string[] tags, TimeSpan?ttl = null, Contracts.When when = Contracts.When.Always)
        {
            if (tags == null || tags.Length == 0)
            {
                SetHashed(key, field, value, ttl, when);
                return;
            }
            var db    = RedisConnection.GetDatabase();
            var batch = db.CreateBatch();

            batch.HashSetAsync(key, field, Serializer.Serialize(value), (When)when);
            // Set the key expiration
            SetMaxExpiration(batch, key, ttl);
            foreach (var tagName in tags)
            {
                var tag = FormatTag(tagName);
                // Add the tag-key->field relation
                batch.SetAddAsync(tag, FormatField(key, field));
                // Set the tag expiration
                SetMaxExpiration(batch, tag, ttl);
            }
            batch.Execute();
        }
        /// <summary>
        /// Set the value of a key, associating the key with the given tag(s).
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="tags">The tags.</param>
        /// <param name="ttl">The expiry.</param>
        /// <param name="when">Indicates when this operation should be performed.</param>
        public void SetObject <T>(string key, T value, string[] tags, TimeSpan?ttl = null, Contracts.When when = Contracts.When.Always)
        {
            if (tags == null || tags.Length == 0)
            {
                SetObject(key, value, ttl, when);
                return;
            }
            var serialized = Serializer.Serialize(value);
            var db         = RedisConnection.GetDatabase();
            var batch      = db.CreateBatch();

            foreach (var tagName in tags)
            {
                var tag = FormatTag(tagName);
                // Add the tag-key relation
                batch.SetAddAsync(tag, key);
                // Set the expiration
                SetMaxExpiration(batch, tag, ttl);
            }
            // Add the key-value
            batch.StringSetAsync(key, serialized, ttl, (When)when);
            batch.Execute();
        }
        /// <summary>
        /// Sets the specified value to a hashset using the pair hashKey+field.
        /// (The latest expiration applies to the whole key)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">The key.</param>
        /// <param name="field">The field key</param>
        /// <param name="value">The value to store</param>
        /// <param name="ttl">Set the current expiration timespan to the whole key (not only this hash). NULL to keep the current expiration.</param>
        /// <param name="when">Indicates when this operation should be performed.</param>
        public void SetHashed <T>(string key, string field, T value, TimeSpan?ttl = null, Contracts.When when = Contracts.When.Always)
        {
            var db    = RedisConnection.GetDatabase();
            var batch = db.CreateBatch();

            batch.HashSetAsync(key, field, Serializer.Serialize(value), (When)when);
            // Set the key expiration
            SetMaxExpiration(batch, key, ttl);
            batch.Execute();
        }
        /// <summary>
        /// Set the value of a key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="ttl">The expiration.</param>
        /// <param name="when">Indicates when this operation should be performed.</param>
        public void SetObject <T>(string key, T value, TimeSpan?ttl = null, Contracts.When when = Contracts.When.Always)
        {
            var serialized = Serializer.Serialize(value);

            RedisConnection.GetDatabase().StringSet(key, serialized, ttl, (When)when);
        }