Что .NET StringComparer эквивалентно SQL Latin1_General_CI_AS

Я реализую уровень кэширования между моей базой данных и моим кодом C #. Идея состоит в том, чтобы кэшировать результаты определенных запросов к БД на основе параметров запроса. В базе данных используется сопоставление по умолчанию - либо SQL_Latin1_General_CP1_CI_AS , либо Latin1_General_CI_AS , которые, как я полагаю, на основе небольшого поиска в Google эквивалентны для равенства, но отличаются для сортировки.

Мне нужен.NET StringComparer, который может дать мне такое же поведение, по крайней мере, для проверки равенства и генерации хэш-кода, которое используется при сортировке базы данных. Цель состоит в том, чтобы иметь возможность использовать StringComparer в словаре .NET в коде C #, чтобы определить, находится ли конкретный строковый ключ уже в кеше или нет.

Действительно упрощенный пример:

var comparer = StringComparer.??? // What goes here?

private static Dictionary<string, MyObject> cache =
    new Dictionary<string, MyObject>(comparer);

public static MyObject GetObject(string key) {
    if (cache.ContainsKey(key)) {
        return cache[key].Clone();
    } else {
        // invoke SQL "select * from mytable where mykey = @mykey"
        // with parameter @mykey set to key
        MyObject result = // object constructed from the sql result
        cache[key] = result;
        return result.Clone();
    }
}
public static void SaveObject(string key, MyObject obj) {
    // invoke SQL "update mytable set ... where mykey = @mykey" etc
    cache[key] = obj.Clone();
}

Причина важности того, чтобы StringComparer соответствовала параметрам сортировки базы данных, заключается в том, что как ложные срабатывания, так и ложные отрицания будут иметь плохие последствия для кода.

Если StringComparer сообщает, что два ключа A и B равны, когда база данных считает, что они различны, тогда в базе данных может быть две строки с этими двумя ключами, но кеш не позволит вернуть вторую строку, если ее спросят. для A и B последовательно - потому что get для B неправильно попадет в кеш и вернет объект, который был получен для A.

Проблема более тонкая, если StringComparer говорит, что A и B различны, когда база данных считает, что они равны, но не менее проблематичны. Вызов GetObject для обоих ключей подойдет и вернет объекты, соответствующие одной и той же строке базы данных. Но затем вызов SaveObject с ключом A приведет к неправильному кешированию; для ключа B по-прежнему будет запись в кэше со старыми данными. Последующий GetObject (B) предоставит устаревшую информацию.

Итак, чтобы мой код работал правильно, мне нужен StringComparer, чтобы он соответствовал поведению базы данных при проверке равенства и генерации хэш-кода. Мой поиск в Google дал много информации о том, что сопоставления SQL и.NET-сравнения не совсем эквивалентны, но нет подробностей о том, в чем заключаются различия, ограничиваются ли они только различиями в сортировке или можно ли найти StringComparer, который эквивалентен специфичному сопоставлению SQL, если универсальное решение не требуется.

(Боковое примечание - уровень кэширования является универсальным, поэтому я не могу делать конкретных предположений о природе ключа и подходящем сопоставлении. Все таблицы в моей базе данных используют одинаковое сопоставление серверов по умолчанию. Я просто необходимо сопоставить существующее сопоставление)

13
задан Alberto 30 May 2014 в 07:13
поделиться