【问题标题】:Can AnsiStrings be used by default with Dapper?AnsiStrings 可以默认与 Dapper 一起使用吗?
【发布时间】:2019-06-12 07:44:19
【问题描述】:

我正在对一个数据库使用 Dapper,其中字符串主要存储在 VarChar 列中。默认情况下,Dapper 在生成查询时使用NVarChar 参数,虽然我可以用DbString 包装我使用的每个字符串参数,但默认情况下使用AnsiStrings 并使用DbString 来处理NVarChar 情况会很棒。

我尝试将 Dapper 源代码中的类型映射从 DbType.String 更改为 DbType.AnsiString,但这似乎会导致参数委托的 IL 生成错误(抛出 InvalidProgramException)。

有更简单的方法吗?

更新

仅更改 typeMap 是不够的,我还需要更改一些 if (dbType == DbType.String) 检查。现在可以了!

【问题讨论】:

  • ansi 字符串没有什么了不起的。 Unicode 无处不在,从你面前的机器和你用来编程的语言开始。当您尝试使用每个人都避免的选项时,一定会遇到麻烦。
  • 我同意,但请告诉 10 年前在 SQL Server 7 上设计 DB 架构的人。无论如何,unicode 应该是默认值,我只是想知道是否有更简单的方法为这个特定的用例更改它。
  • 在数据库中以 unicode 形式存储内容几乎会使消耗的字节量增加一倍,因此如果您使用 nvarchars 代替,则需要大量增加所需的数据。空间不是这个问题,但这肯定会影响性能,例如如果您使用 nvarchar(max) 而不是 varchar(max),则您刚刚将 SQL Server 中 1 行中的数据量减半。所以你需要 .Net 中的 ansistrings 以避免在将变量传递给 db 时进行隐式转换

标签: c# dapper


【解决方案1】:

您可以在不修改源代码的情况下完成此操作。

Dapper.SqlMapper.AddTypeMap(typeof(string), System.Data.DbType.AnsiString);

设置一次会将所有字符串调整为 varchar。

【讨论】:

【解决方案2】:

要默认使用 ansistrings,我必须(参考 NuGet 的 Dapper 1.3 源代码):

  • 更改类型映射以在 L164 上使用 DbType.AnsiString 而不是 DbType.String
  • 在方法CreateParamInfoGenerator 中更改对L960、L968、L973 的检查以包括DbType.AnsiStringDbType.String

无效 IL 的问题似乎是 L1000 上代码的后面分支检查 typeof(string) 而前面的分支使用 DbType

这样做一切都很好 - 不再有索引扫描!

【讨论】:

    猜你喜欢
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2011-08-15
    • 2018-02-16
    • 2020-06-30
    • 2014-11-15
    相关资源
    最近更新 更多