如何使Service Fabric可靠集合不区分大小写?

问题描述 投票:1回答:1

我有一个Stateful Service Fabric服务,使用以下代码创建的IReliableDictionary创建,更新或读取数据:

var dictionary = await StateManager.GetOrAddAsync<IReliableDictionary<string, Entry>>(ReliableDictionaryName);

// Read
using (ITransaction tx = StateManager.CreateTransaction())
{
    ConditionalValue<Entry> result = await dictionary.TryGetValueAsync(tx, name);
    return result.HasValue ? result.Value : null;
}

// Create or update
using (ITransaction tx = StateManager.CreateTransaction())
{
    await dictionary.AddOrUpdateAsync(tx, entry.Name, entry, (key, prev) => entry);
    await tx.CommitAsync();
}    

它有效,但它区分大小写。有没有办法让Reliable集合存储并以不区分大小写的方式获取数据,除了将.ToLower()应用于密钥,这有点像hacky?

c# service-fabric-stateful azure-service-fabric reliable-dictionary
1个回答
0
投票

您看到的这种行为主要是C#中默认情况下比较字符串的属性。可靠的字典使用密钥的IEquatableIComparable实现来执行查找。如果string的默认行为不适合您,您可以实现一种以您希望的方式执行字符串比较的类型。然后,使用新类型作为可靠字典的键。您可以实现隐式运算符以在原始字符串和自定义类型之间进行转换,从而使用法无痛。这是一个例子:

using System.Runtime.Serialization;

    [DataContract]
    public class CaseInsensitiveString : IEquatable<CaseInsensitiveString>,
                                         IComparable<CaseInsensitiveString>
    {
        #region Constructors

        public CaseInsensitiveString(string value)
        {
            this.Value = value;
        }

        #endregion

        #region Instance Properties

        [DataMember]
        public string Value
        {
            get;
            set;
        }

        #endregion

        #region Instance Methods

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null,
                                obj))
            {
                return false;
            }

            if (ReferenceEquals(this,
                                obj))
            {
                return true;
            }

            if (obj.GetType() != this.GetType())
            {
                return false;
            }

            return this.Equals((CaseInsensitiveString)obj);
        }

        public override int GetHashCode()
        {
            return this.Value != null
                       ? this.Value.GetHashCode()
                       : 0;
        }

        public int CompareTo(CaseInsensitiveString other)
        {
            return string.Compare(this.Value,
                                  other?.Value,
                                  StringComparison.OrdinalIgnoreCase);
        }

        public bool Equals(CaseInsensitiveString other)
        {
            if (ReferenceEquals(null,
                                other))
            {
                return false;
            }

            if (ReferenceEquals(this,
                                other))
            {
                return true;
            }

            return string.Equals(this.Value,
                                 other.Value,
                                 StringComparison.OrdinalIgnoreCase);
        }

        #endregion

        #region Class Methods

        public static bool operator ==(CaseInsensitiveString left,
                                       CaseInsensitiveString right)
        {
            return Equals(left,
                          right);
        }

        public static implicit operator CaseInsensitiveString(string value)
        {
            return new CaseInsensitiveString(value);
        }

        public static implicit operator string(CaseInsensitiveString caseInsensitiveString)
        {
            return caseInsensitiveString.Value;
        }

        public static bool operator !=(CaseInsensitiveString left,
                                       CaseInsensitiveString right)
        {
            return !Equals(left,
                           right);
        }

        #endregion
    }

© www.soinside.com 2019 - 2024. All rights reserved.