#c# #service-fabric-stateful #azure-service-fabric #reliable-dictionary
#c# #service-fabric-с сохранением состояния #azure-service-fabric #надежный-словарь
Вопрос:
У меня есть служба Service Fabric с отслеживанием состояния, и я создаю, обновляю или считываю данные, используя IReliableDictionary
created с помощью следующего кода:
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()
к ключам, что довольно банально?
Ответ №1:
Это поведение, которое вы видите, в основном является свойством того, как строки сравниваются по умолчанию в C #. Надежные словари используют реализацию ключа IEquatable
и IComparable
для выполнения поиска. Если поведение 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
}