我正在数据库和C代码之间实现一个缓存层。其思想是基于查询的参数来缓存某些db查询的结果。数据库使用的是默认的排序规则-要么SQL_Latin1_General_CP1_CI_AS
要么Latin1_General_CI_AS
,我相信基于一些简短的谷歌搜索,这对于等式来说是等价的,对于排序来说则是不同的。
我需要一个.NET StrimeCalpor,它可以给我相同的行为,至少对于数据库的排序使用的是相等测试和哈希代码生成。目标是能够在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,缓存将阻止返回第二行,因为get for b将错误地命中缓存并返回检索到的对象。
如果stringcomparer说a和b是不同的,而数据库认为它们是相等的,那么问题就更微妙了,但问题并没有减少。对两个键的getobject调用都可以,并返回对应于同一数据库行的对象。但是,使用键a调用saveobject会使缓存不正确;对于键b,仍会有一个缓存条目包含旧数据。随后的getobject(b)将给出过时的信息。
因此,为了使代码正常工作,我需要stringcomparer来匹配用于相等性测试和hashcode生成的数据库行为。到目前为止,我在google上搜索到的大量信息表明,sql排序规则和.net比较并不完全相同,但没有详细说明它们之间的区别,它们是否仅限于排序方面的差异,或者,如果不需要通用解决方案,是否可以找到与特定sql排序规则等效的stringcomparer。
(附带说明-缓存层是通用的,所以我不能对键的性质和排序规则做特定的假设。数据库中的所有表共享相同的默认服务器排序规则。我只需要匹配存在的排序规则)
最佳答案
看看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>
。
关于c# - .NET StringComparer等效于SQL的Latin1_General_CI_AS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9384642/