Dapper.NETで文字列をトリムする

c# dapper sql

質問

私はDapper.NETをしばらく使っています。 Dapperに文字列をトリムすることがオブジェクトのプロパティに割り当てられるようにすることが可能かどうか疑問に思っていました。

私は現在、SQLでLTRIM(RTRIM(fieldname)) 、および/またはプロパティセッターでvalue.Trim()またはvalue.Trim()しています。

しかし、私はvarcharの代わりにcharsを使用するレガシーデータベースを使って作業しています。すべてをトリミングしなければならない時間を減らす方法があるのだろうかと思っていました。

私はdapperのソースコードを編集することで自分自身を手に入れましたが、他のマッピングなどを壊してしまいました。

誰かがこのオーバーヘッドを減らすことができる提案があったかどうかだけに疑問がありました。 (私は何かが非常に簡単に欠けているかもしれません!)

私はC#3.5で作業しています。

受け入れられた回答

私はDapperを直接修正するという考えは好きではなかった。私は、Dapperを包む拡張メソッドを作成し、その結果を反映させるだけで問題を解決し、すべての文字列プロパティをトリムすることにしました。

public static class DapperExtensions {
    public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) {
        var dapperResult = SqlMapper.Query<T>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
        var result = TrimStrings(dapperResult.ToList());
        return result;
    }

    static IEnumerable<T> TrimStrings<T>(IList<T> objects) {
        //todo: create an Attribute that can designate that a property shouldn't be trimmed if we need it
        var publicInstanceStringProperties = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType == typeof (string) && x.CanRead &&  x.CanWrite);
        foreach (var prop in publicInstanceStringProperties) {
            foreach (var obj in objects) {
                var value = (string) prop.GetValue(obj);
                var trimmedValue = value.SafeTrim();
                prop.SetValue(obj, trimmedValue);
            }
        }
        return objects;
    }

    static string SafeTrim(this string source) {
        if (source == null) {
            return null;
        }
        return source.Trim();
    }
}

私の解決策(Dapperと同じ名前を使用したかったので)は、拡張メソッドの解決法がどのように機能するかという点で重要です


人気のある回答

マット、

これは非常に簡単に行うことができます。私はこの変更を行ってSQLのcharスペースをきれいにしました。私はそれをテストして、私のコードは変化のために遅さがあれば兆候を示さない。

まず 、元のソースコードをバックアップして、必要に応じて元に戻すことが容易になるようにします。

次のメソッドを作成します。

public static string ReadString(object value) /*** CUSTOM CODE ***/
{
    if (value == null || value is DBNull) return null; 
    return value.ToString().Trim();
}

私はいつも/ * CUSTOM CODE *を使ってすべてのコード変更をマークします。

次に 、次のメソッドを見つけます。

public static void SetTypeMap(Type type, ITypeMap map)

その方法で次の行を探します:

if (memberType == typeof (char) || memberType == typeof (char?))
{
    il.EmitCall(OpCodes.Call, typeof (SqlMapper).GetMethod(
        memberType == typeof (char) ? "ReadChar" : "ReadNullableChar",
        BindingFlags.Static | BindingFlags.Public), null);
        // stack is now [target][target][typed-value]
}
else

次のように変更します。

if (memberType == typeof (char) || memberType == typeof (char?))
{
    il.EmitCall(OpCodes.Call, typeof (SqlMapper).GetMethod(
        memberType == typeof (char) ? "ReadChar" : "ReadNullableChar",
        BindingFlags.Static | BindingFlags.Public), null);
        // stack is now [target][target][typed-value]
}
else if (memberType == typeof(string)) /*** CUSTOM CODE START ***/
{
    il.EmitCall(OpCodes.Call, typeof(SqlMapper).GetMethod("ReadString", BindingFlags.Static | BindingFlags.Public), null);
    // stack is now [target][target][typed-value]
}    /*** CUSTOM CODE END ***/
else

コンパイルして準備完了です



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ