13

我在 Dapper .NET 项目主页上找到了以下评论。

Dapper 支持 varchar 参数,如果您使用参数在 varchar 列上执行 where 子句,请确保以这种方式传递它:

    Query<Thing>("select * from Thing where Name = @Name", new {Name = 
    new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在 Sql Server 上,查询 unicode 时使用 unicode 和查询非 unicode 时使用 ansi 至关重要

我正在评估 Dapper 是否与旧数据库 (SQL Server 2008) 一起使用,其中包含许多带有 varchar 参数的存储过程,我对这个限制有点困惑。

使用手工制作的 ADO.NET 代码,我将对上述查询使用以下内容:

new SqlParameter("@Name", "abcde")

没有指定它是否是 unicode,也没有指定长度。

  • 为什么我需要这种带有 Dapper 的冗长 DbString 语法,指定列长度、IsFixedLength 和 IsAnsi?

  • 为什么 IsFixedLength = true 对于 varchar 列(我希望它对于 char 或 nchar 列是正确的)?

  • 我必须像这样使用 DbString 来存储过程参数吗?

我期待 Dapper 使我的 DAL 代码更简洁,但这似乎使它对于 varchar 参数更加冗长。

更新

我进行了更深入的研究,试图理解为什么 Dapper 会有这种 varchar 限制,而我的手工代码中似乎没有这种限制,我通常会在其中创建一个输入参数,如下所示:

var parameter = factory.CreateParameter(); // Factory is a DbProviderFactory
parameter.Name = ...;
parameter.Value = ...;

DbType并且通常让提供者使用自己的规则来推断,除非我特别想强制它。

查看 Dapper 的DynamicParameters类,它有一个AddParameters创建参数的方法,如下所示:

var dbType = param.DbType; // Get dbType and value
var val = param.Value;     // from 

...
// Coerce dbType to a non-null value if val is not null !!!!!
if (dbType == null && val != null) dbType = SqlMapper.LookupDbType(val.GetType(),name);
...
var p = command.CreateParameter();
...
if (dbType != null)                     
{                         
    p.DbType = dbType.Value;                     
}

即,它明确地强制IDataParameter.DbType使用它自己的算法查找的值,而不是让提供者使用它自己的规则。

这有充分的理由吗?这对我来说似乎是错误的,特别是考虑到关于 Dapper 对 varchar 参数的支持的评论。

4

2 回答 2

0

使用 ODBC 时需要此语法。

您需要在 c# 中为 Dapper 定义一个 CHAR(30) 字段作为 DbString,并设置长度 (30) 和 ansi (true) 值以防止 Dapper 假定字符串是文本/blob 类型。否则,您可能会收到错误:“非法尝试转换文本/字节 blob 类型”。

我使用 ODBC 连接到 Informix 时遇到此错误,直到我将参数定义为 DbString() 并设置长度和 ansi 值。

更多信息在这里

于 2017-03-28T13:25:41.100 回答
-3
var param = new { Varchar1 = "", Varchar2 = "" };
db.Query("SP", param, commandType:CommandType.StoredProcedure);
于 2016-09-29T08:02:07.423 回答