Привет, читатели!
Нужен ваш коллективный разум для решения следующей головоломки. Сразу скажу, что мы уже перепробовали много способов для ее решения, но так и не смогли понять в чем проблема, хотя может быть ответ лежит на поверхности и мы его не замечаем.
Дисклэймер
Весь код является потокобезопасным, нам удалось локализовать проблему и я приведу немного упрощенную версию кода, но суть проблемы не меняется. Сразу скажу, что, возможно, код не идеален и можно было написать по-другому, но мы имеем, то что имеем и сейчас нас интересует именно суть ошибки.
Итак, дано
Есть функция GetHash, которая возвращает MD5 хэш строки. Я приведу коротенький пример ее использования, чтобы можно было его скопировать и запустить:
static string GetHash(string text)
{
var hash = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(text));
var stringBuilder = new StringBuilder();
for (var i = 0; i < hash.Length; i++)
stringBuilder.Append(hash[i].ToString("x2"));
return stringBuilder.ToString();
}
static void Main(string[] args)
{
var scope = "~/Views/Atlas/Index.cshtml";
var text = "World Data Atlas";
System.Console.WriteLine("Hash: " + GetHash(scope.ToLower() + text));
System.Console.ReadKey();
}
Эта программа вернет значение 'b0b714f818a3c2dfa7d84ff28575eb1d', которое является правильным. В нашем коде мы используем функцию GetHash и затем сохраняем объект в БД с следующими полями:
- Hash varchar(255)
- Scope varchar(255)
- Text nvarchar(MAX)
Проблема
Каким то образом в базу сохраняется неправильно значение Hash для пары Scope+Text:
Hash | Scope | Text |
---|---|---|
b0b714f818a3c2dfa7d84ff28575eb1d | ~/Views/Atlas/Index.cshtml | World Data Atlas |
559ae9439621091761d89d94e8572eeb | ~/Views/Atlas/Index.cshtml | World Data Atlas |
В первой строке правильное значение Hash, а во второй нет. В результате мы имеем дубликаты. В качестве ORM мы используем NHibernate. Для маппинга классов используеся библиотека Fluent NHibernate.
Честно говоря, проблема нам уже порядком надоела и мы будем рады любой идее.
Автор: polyakova