.Net框架中是否有一个内置类可以用来表示AnsiString?

发布于 2024-11-08 03:54:52 字数 989 浏览 0 评论 0原文

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

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

特定参数的 DbType.StringDbType.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 的容器,其语义与上面的示例类似?

For dapper I need to build support for passing in AnsiString params.

Databases have both unicode and non-unicode strings, picking the right parameter type is sometimes crucial.

DbType.String vs DbType.AnsiString for a particular param can heavily effect perf.

In dapper we pass in parameters dynamically, Eg:

Query<User>("select * from Users where Name=@Name", new {Name = "name"});

I have an internal map that says that if I see typeof(String) I know to pass in the param as a DbType.String

However, I would like my users to be able to denote that the string should be an AnsiString. Attributes are not supported for anonymous classes, so I need a distinct type for this.

Clearly I can invent one:

public class AnsiString 
{
    private readonly string str;
    public AnsiString(string str)
    {
        this.str = str;
    }

    public String Value { get { return str; } }
}

Which would give me the clean API:

Query<User>("select * from Users where Name=@Name", 
   new {Name = new AnsiString("name")});

However, why invent one if such a class exists in System.Data or the BCL.

Is there a type somewhere in the BCL or System.Data I could use as a container for AnsiString, with similar semantics to the sample above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无名指的心愿 2024-11-15 03:54:52

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

So;它支持:

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

类型可用dapper 内。

There is not such class in the BCL or System.Data, you will have to roll your own.

We went with a custom type to provide more fine-grained customn in the end; this test shows typical usage:

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

So; it supports:

  • ansi vs unicode
  • fixed vs dynamic length
  • in the case of dynamic length, explict vs implicit (4000 if the length is <= 4000; "max" otherwise - this keeps the number of query-plans sane)

The type is available inside dapper.

猫弦 2024-11-15 03:54:52

我想您可以将 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()});

I guess you can use string for DbType.String and char[] for DbType.AnsiString.

It will look very similar to your current code:

Query<User>("select * from Users where Name=@Name", new {Name = "name".ToCharArray()});

Or if you wan use your AnsiString, you can create extension method .ToAnsiString():

public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文