Dapper.NET으로 문자열 다듬기

c# dapper sql

문제

나는 잠시 동안 Dapper.NET 을 사용 Dapper.NET . Dapper가 문자열을 잘라내어 객체의 속성에 할당 할 수 있는지 궁금합니다.

현재 SQL에서 LTRIM(RTRIM(fieldname)) 및 / 또는 속성 설정자의 value.Trim() 을 사용합니다.

그러나 varchar 대신 chars를 사용하는 레거시 데이터베이스로 작업하고 있으며 모든 것을 다듬어야하는 시간을 줄이는 방법이 있는지 궁금합니다.

나는 dapper의 소스 코드를 편집하여 나 자신을 가졌지 만 다른 매핑 등을 깨뜨리는 결과를 낳았다.

이 오버 헤드를 줄일 수있는 제안이 있다면 누구나 궁금해 할 것입니다. (나는 아주 간단한 것을 놓칠지도 모른다!)

나는 C # 3.5와 함께 작업하고 있습니다.

수락 된 답변

Dapper를 직접 수정하는 아이디어가 마음에 들지 않았습니다. Dapper 's를 감싸는 확장 메서드를 만들어서 문제를 해결하기로 결정하고 결과를 반영하고 모든 문자열 속성을 다듬기로 결정했습니다.

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
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow