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パラメーターのサポートに関するコメントに照らして、私には間違っているようです。