.Net框架中是否有一个内置类可以用来表示AnsiString?
-
07-09-2020 - |
题
对于 dapper,我需要构建对传入 AnsiString 参数的支持。
数据库同时具有 unicode 和非 unicode 字符串,选择正确的参数类型有时至关重要。
DbType.String
与 DbType.AnsiString
对于特定的参数会严重影响性能。
在 dapper 中我们动态传入参数,例如:
Query<User>("select * from Users where Name=@Name", new {Name = "name"});
我有一张内部地图,上面写着如果我看到 typeof(String)
我知道将参数作为 DbType.String
但是,我希望我的用户能够指示该字符串应该是 AnsiString。匿名类不支持属性,因此我需要一个不同的类型。
显然我可以发明一个:
public class AnsiString
{
private readonly string str;
public AnsiString(string str)
{
this.str = str;
}
public String Value { get { return str; } }
}
这会给我干净的 API:
Query<User>("select * from Users where Name=@Name",
new {Name = new AnsiString("name")});
然而,如果 System.Data 或 BCL 中存在这样的类,为什么还要发明一个呢?
BCL 中是否有某种类型或 System.Data
我可以用作容器 AnsiString
, ,与上面的示例具有相似的语义?
解决方案
BCL 或 System.Data 中没有这样的类,您必须自己编写。
我们选择了自定义类型,以最终提供更细粒度的自定义;该测试显示了典型用法:
public void TestDbString()
{
var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
new
{
a = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true },
b = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = false },
c = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = true },
d = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = false },
e = new DbString { Value = "abcde", IsAnsi = true },
f = new DbString { Value = "abcde", IsAnsi = false },
}).First();
((int)obj.a).IsEqualTo(10);
((int)obj.b).IsEqualTo(20);
((int)obj.c).IsEqualTo(5);
((int)obj.d).IsEqualTo(10);
((int)obj.e).IsEqualTo(5);
((int)obj.f).IsEqualTo(10);
}
所以;它支持:
- ansi 与 unicode
- 固定长度与动态长度
- 在动态长度的情况下,显式与隐式(如果长度 <= 4000 则为 4000;否则为“max” - 这使查询计划的数量保持正常)
该类型在里面可用 衣冠楚楚.
其他提示
我想你可以使用 string
为了 DbType.String
和 char[]
为了 DbType.AnsiString
.
它看起来与您当前的代码非常相似:
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToCharArray()});
或者,如果您想使用 AnsiString,您可以创建扩展方法 .ToAnsiString()
:
public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
不隶属于 StackOverflow