我需要一个.NET StringComparer,可以给我相同的行为,至少对于等式测试和哈希码生成,正如数据库的归类正在使用的那样.目标是能够使用C#代码中的.NET字典中的StringComparer来确定特定的字符串键是否已经在缓存中.
一个真正简化的例子:
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连续 – 因为获取B将不正确地命中缓存并返回检索到的对象A.
如果StringComparer说当数据库相信它们相同时,A和B不同,那么问题就更微妙了,但是也不会有问题.对于这两个键的GetObject调用将会很好,并返回对应于同一数据库行的对象.但是用键A调用SaveObject会使缓存不正确;仍然有一个具有旧数据的密钥B的缓存条目.随后的GetObject(B)将给出过时的信息.
所以为了使我的代码正常工作,我需要StringComparer来匹配数据库行为以进行相等性测试和哈希码生成.到目前为止,我的谷歌搜索已经产生了很多关于sql排序和.NET比较不完全相同的事实的信息,但是没有关于差异的细节,无论它们是仅限于排序中的差异,还是可以找到一个StringComparer,如果不需要通用解决方案,则相当于特定的sql排序规则.
(旁注 – 缓存层是通用目的,所以我不能对密钥的性质和归类是合适的做出特定的假设.我的数据库中的所有表共享相同的默认服务器排序规则,我只需要匹配整理存在)
解决方法
CollationInfo
课.它位于一个名为Microsoft.sqlServer.Management.sqlParser.dll的程序集中,尽管我不完全知道从哪里得到这个.有一个静态列表
Collations
(名称)和静态方法
GetCollationInfo
(按名称).
每个CollationInfo都有一个Comparer
.它与StringComparer不完全相同,但功能类似.
编辑:Microsoft.sqlServer.Management.sqlParser.dll是共享管理对象(SMO)包的一部分.此功能可以在这里下载到sql Server 2008 R2:
http://www.microsoft.com/download/en/details.aspx?id=16978#SMO
编辑:CollationInfo确实有一个名为EqualityComparer
的属性,它是一个IEqualityComparer< string> ;.