Последние три дня я боролся с забавным, по крайней мере для меня, поведением.Основная концепция заключается в следующем: объект создается в памяти, этот объект имеет список дочерних элементов.Этот объект сохраняется в БД, дети также сохраняются, каскадный режим.Это работает нормально, но если после сохранения я пытаюсь удалить одного потомка, удалив из списка, это не сработает, список не удалит потомка.Я обнаружил, что список типа HashedSet
каким-то образом кэширует хэш-код объекта, когда он впервые добавляется в список, перед сохранением, после сохранения тот же объект не имеет того же хеш-кода.Но список все еще предполагает старый хэш-код.Я переопределил GetHashCode
и Equals
, после долгих поисков и поисков, я обнаружил сообщение в блоге , в котором объясняется использование nhibernate для методов GetHashCode
и Equals
.
Это моя реализация
public override int GetHashCode()
{
if (orgHashCode.HasValue)
return orgHashCode.Value;
var hashCode = 17;
var signatureProperties = GetSignatureProperties();
if (!IsTransient())
hashCode = (hashCode*HASH_MULTIPLIER) ^ GetIdValue().GetHashCode();
else
{
foreach (var property in signatureProperties)
{
object value = property.GetValue(this, null);
if (value != null)
hashCode = (hashCode*HASH_MULTIPLIER) ^ value.GetHashCode();
}
}
if (!orgHashCode.HasValue)
orgHashCode = hashCode;
// If no properties were flagged as being part of the signature of the object,
// then simply return the hashcode of the base object as the hashcode.
return signatureProperties.Any() ? hashCode : base.GetHashCode();
}
public override bool Equals(object obj)
{
var compareTo = obj as DbCommonBase;
if (ReferenceEquals(this, compareTo))
return true;
return compareTo != null &&
GetType().Equals(compareTo.GetUnproxiedType()) &&
(HasSameNonDefaultIdAs(compareTo) || ((IsTransient()) || compareTo.IsTransient()) &&
HasSameObjectSignatureAs(compareTo));
}
Я использовал переменную orgHashCode, которая возвращает хеш-код перед первым сгенерированным хеш-кодом, если я использую этот метод, кажется, что он работает, но я думаю, чтоэто не лучшее решение, хеш-код должен генерироваться для текущего объекта, а не для «его первой версии».
Я не знаю, достаточно ли понятно мое объяснение.Любые советы будут высоко оценены.Спасибо