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 を使用することが重要です。

私は、varchar パラメータを持つ多数のストアド プロシージャを使用するレガシー データベース (SQL Server 2008) で使用する Dapper を評価していますが、この制限に少し戸惑っています。

手作りの ADO.NET コードでは、上記のクエリに次のコードを使用します。

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

ユニコードかどうか、長さを指定せずに。

  • 列の長さ、IsFixedLength、IsAnsi を指定して、Dapper でこの冗長な DbString 構文が必要なのはなぜですか?

  • IsFixedLength = varchar 列で true になるのはなぜですか (char または nchar 列では true になると思います)。

  • ストアド プロシージャのパラメーターには、このように 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