对于dapper我需要建立对传递AnsiString参数的支持。
数据库具有unicode和非unicode字符串,选择正确的参数类型有时至关重要。
某个特定参数的 DbType.String
vs 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
的容器,其语义与上述示例类似?
答案 0 :(得分:1)
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);
}
因此;它支持:
该类型在dapper内可用。
答案 1 :(得分:0)
我猜您可以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()});