2

ntextDapper でSQL Server CE の型をサポートする必要があります。問題を説明するスレッドがここにあります: https://code.google.com/p/dapper-dot-net/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone %20Owner%20Summary&groupby=&sort=&id=110

PetaPoco で使用されているアプローチと同様のソリューションを使用するように Dapper を変更しようとしました

Dapper のソースを調べた後、これを試みる良い方法はDbStringクラスを変更することではないかと判断しました。AddParameter(IDbCommand command, string name)メソッド (3120 行目から) を次のように変更しました。

public void AddParameter(IDbCommand command, string name)
{
            if (IsFixedLength && Length == -1)
            {
                throw new InvalidOperationException("If specifying IsFixedLength,  a Length must also be specified");
            }
            var param = command.CreateParameter();
            param.ParameterName = name;
            param.Value = (object)Value ?? DBNull.Value;
            if (Length == -1 && Value != null && Value.Length <= 4000)
            {
                param.Size = 4000;
            }
            else
            {
                param.Size = Length;
            }
            param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String);

            if (param.Value != null)
            {
                if (param.Value.ToString().Length + 1 > 4000 && param.GetType().Name == "SqlCeParameter")
                {
                    param.GetType().GetProperty("SqlDbType").SetValue(param, System.Data.SqlDbType.NText, null);  
                }
            }

            command.Parameters.Add(param);
}

私の編集は、タイプをチェックして に変更しようとする下の方の部分ntextです。しかし、このコードを実行すると、IIS Express がクラッシュし、asp.net から有用なデバッグ情報が得られません。デバッガーで実行しようとしましたが、ヒープの破損に関連するエラーが発生しました。

私はここで間違った道を進んでいますか?Dapper でこのようなことを試みるより良い方法はありますか? それとも、キャッシュや IL が生成される方法が原因でうまくいかないのでしょうか? 動作するようになったら、プル リクエストを作成したいと思っていましたが、打ちのめされます。


更新 - 1 つの潜在的な解決策を見つけました。クラスのAddParameters(IDbCommand command, SqlMapper.Identity identity)メソッドにコードを追加しました。DynamicParametersメソッドの最終行は次のようになります。

if (s != null)
{
    if (s.Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")    
    {
        p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
        p.Size = s.Length;
    }
}
if (add)
{
    command.Parameters.Add(p);
}
param.AttachedParam = p;

このソリューションを使用するには、パラメーターを DynamicParameters として追加する必要があります。したがって、機能しますが、最も有用な方法ではありません。私はまだより良い解決策を探しています。

これは、私がプル リクエストを作成した場合に、Dapper 開発者がパッチとして含めることを検討するようなものですか?

4

1 に答える 1

1

この拡張メソッドを任意のプロパティ バッグに試してください。

    public static class DynamicParametersExtensions
{
    public static DynamicParameters AsDynamic(this object propertyBag) {
        var parameters = new DynamicParameters();
        foreach (var property in propertyBag.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
            var propertyValue = property.GetValue(propertyBag);
            var propertyValueAsString = propertyValue as string;
            if (propertyValueAsString != null && propertyValueAsString.Length >= 4000) {
                parameters.Add(property.Name, new DbString {
                    Value = propertyValueAsString,
                    Length = propertyValueAsString.Length
                });
            } else {
                parameters.Add(property.Name, propertyValue);
            }
        }
        return parameters;
    }
}

使用例:

connection.Execute(@"UPDATE MyTable SET NTextColumn=@NTextColumn", new { value.NTextColumn }.AsDynamic()); 
于 2015-07-30T15:39:29.137 に答える