精致和varchars

时间:2013-10-14 14:05:38

标签: varchar dapper

我在the Dapper .NET project home page找到了以下评论。

  

Dapper支持varchar参数,如果使用param在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和ansi查询非unicode时使用unicode至关重要

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

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

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

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

  • 为什么我需要使用Dapper的详细DbString语法,指定列长度,IsFixedLength和IsAnsi?

  • 为什么varchar列的IsFixedLength = true(我希望char或nchar列为true)?

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

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

更新

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

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参数的评论。

2 个答案:

答案 0 :(得分:0)

使用ODBC时需要这种语法。

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

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

More info here

答案 1 :(得分:-2)

var param = new { Varchar1 = "", Varchar2 = "" };
db.Query("SP", param, commandType:CommandType.StoredProcedure);