首页 > 解决方案 > 如何使 Service Fabric Reliable 集合不区分大小写?

问题描述

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

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-statefulazure-service-fabricreliable-dictionary

解决方案


您看到的这种行为主要是 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
    }


推荐阅读