4

对于 dapper,我需要构建对传入 AnsiString 参数的支持。

数据库同时具有 unicode 和非 unicode 字符串,选择正确的参数类型有时至关重要。

DbType.StringvsDbType.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,其语义与上面的示例相似?

4

2 回答 2

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);
}

所以; 它支持:

  • ansi 与 unicode
  • 固定与动态长度
  • 在动态长度的情况下,显式与隐式(如果长度 <= 4000,则为 4000;否则为“max” - 这使查询计划的数量保持正常)

该类型在dapper内部可用。

于 2011-05-20T09:03:36.307 回答
0

我想你可以使用stringforDbType.Stringchar[]for 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()});
于 2011-05-20T08:05:30.057 回答