Как сделать коллекции Service Fabric Reliable без учета регистра?
У меня есть служба 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 collection store и получать данные без учета регистра, кроме применения .ToLower()
к ключам, что отчасти хакерское?
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
}