Recortar cadena con Dapper.NET

c# dapper sql

Pregunta

He estado usando Dapper.NET desde hace un tiempo. Me preguntaba si es posible hacer que Dapper recorte cuerdas, ya que las asigna a las propiedades del objeto.

Actualmente uso LTRIM(RTRIM(fieldname)) en el SQL y / o value.Trim() en el setter de propiedades.

Sin embargo, estoy trabajando con una base de datos heredada que usa caracteres en lugar de varchar, y me preguntaba si había alguna manera de reducir mi tiempo de tener que recortar todo.

Tuve una oportunidad editando el código fuente de Dapper, pero terminé rompiendo otros mapeos, etc. Así que cedí.

Solo me preguntaba si alguien tenía alguna sugerencia que pudiera reducir esta sobrecarga. (¡Me puede estar perdiendo algo muy simple!)

Estoy trabajando con C # 3.5 por cierto.

Respuesta aceptada

No me gustó la idea de modificar Dapper directamente. Decidí resolver el problema creando un método de extensión para ajustar Dapper y simplemente reflexionar sobre el resultado y recortar todas las propiedades de cadena.

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();
    }
}

Crucial para mi solución (ya que quería usar el mismo nombre que Dapper) es cómo funciona la resolución del método de extensión, que puede leer aquí .


Respuesta popular

Mate,

Esto puede hacerse bastante fácil. Hice este cambio para limpiar los espacios de char SQL. Lo he probado y mi código no muestra signos de lentitud debido al cambio.

Primero, asegúrese de hacer una copia de seguridad de su código fuente de salida para que sea más fácil revertirlo en caso de que lo necesite.

Siguiente Crea el siguiente método:

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

Siempre marcó todos los cambios de mi código con / * CUSTOM CODE * / para que luego pueda encontrar mis cambios fácilmente

Luego encuentra el siguiente método:

public static void SetTypeMap(Type type, ITypeMap map)

ahora en ese método, busque las siguientes líneas:

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

y modificar de la siguiente manera:

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

Compila y estás listo para ir



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow