Как сделать коллекции Service Fabric Reliable нечувствительными к регистру?

У меня есть служба 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();
}    

Он работает, но чувствителен к регистру. Есть ли способ сделать надежное хранилище коллекций и получать данные без учета регистра, за исключением применения .ToLower() к ключам, что является своего рода хакерством?


person Yeldar Kurmangaliyev    schedule 12.04.2019    source источник


Ответы (1)


Такое поведение, которое вы видите, в основном является свойством того, как строки по умолчанию сравниваются в C #. Надежные словари используют реализацию ключа IEquatable и IComparable для выполнения поиска. Если поведение строки по умолчанию для вас не работает, вы можете реализовать тип, который выполняет сравнение строк так, как вы хотите. Затем используйте новый тип как ключ к надежному словарю. Вы можете реализовать неявные операторы для преобразования между необработанными строками и пользовательским типом, чтобы сделать использование безболезненным. Вот пример:

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
    }

person abarger    schedule 12.04.2019