C # Database Mapper

c# dapper orm

Pregunta

Estaba buscando asignar los resultados de mi consulta a la base de datos para escribir con fuerza objetos en mi código c #. Así que escribí un método auxiliar rápido y sucio en la clase SqlConnection que ejecuta la consulta en la base de datos y utiliza la reflexión para asignar las columnas de registro a las propiedades del objeto. El código está abajo:

 public static T Query<T>(this SqlConnection conn, string query) where T : new()
    {
        T obj = default(T);

        using (SqlCommand command = new SqlCommand(query, conn))
        {
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    obj = new T();

                    PropertyInfo[] propertyInfos;
                    propertyInfos = typeof(T).GetProperties();

                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        var name = reader.GetName(i);

                        foreach (var item in propertyInfos)
                        {
                            if (item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) && item.CanWrite)
                            {
                                item.SetValue(obj, reader[i], null);
                            }
                        }

                    }
                }
            }
        }

        return obj;
    }

  public class User
    {
        public int id { get; set; }
        public string firstname { get; set; }
        public string lastname { get; set; }
        public DateTime signupDate { get; set; }
        public int age { get; set; }
        public string gender { get; set; }
    }


   var user = conn.Query<User>("select id,firstname,lastname from users");      

Solo quería una segunda opinión sobre mi enfoque anterior de usar la reflexión para vincular los valores, si hay algo que pueda hacer mejor en el código anterior. ¿O si hay algún otro enfoque totalmente diferente que pueda tomar para obtener el mismo resultado?

Creo que probablemente pueda mejorar el código en el método de ayuda eliminando el bucle de propertyInfos y usando un diccionario en su lugar. ¿Hay algo más que deba modificarse?

PD: soy consciente de Dapper, solo quería implementar algo similar por mi cuenta para ayudarme a aprender mejor.

Respuesta aceptada

Lo que has hecho es básicamente lo que hace linq-to-sql u otros mapeadores OR bajo el capó. Para conocer los detalles de cómo funciona, siempre es una buena idea escribir algo desde cero.

Si quieres más inspiración o quieres tener algo que esté listo para producción, utilízalo desde el primer momento. Recomiendo leer en linq-to-sql. Es liviano, pero competente.


Respuesta popular

Hay algunas cosas en las que puedo pensar:

  1. Creo que para saltar el loop puedes usar:

    reader[item.Name]
    
  2. He hecho algo similar, pero nunca me encontré con Dapper. No estoy seguro de si utiliza el reflejo, pero siempre es una buena idea leer el código de otra persona para agudizar sus habilidades (Scott Hanselman recomienda con frecuencia hacerlo).

  3. También puede consultar: http://www.codeproject.com/KB/database/metaquery_part1.aspx

  4. Puede implementar un atributo que mapea un campo en una columna de base de datos, pero eso es solo por diversión.

Editar:

5: También puede omitir el ciclo while sobre el lector y solo tomar la primera fila, y documentar el hecho de que su consulta solo devuelve un objeto, por lo que no extrae mil filas si la consulta devuelve mil filas.



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