Dapper no advierte o falla con datos faltantes

c#-4.0 dapper orm

Pregunta

Digamos que tengo una clase (simplista, por ejemplo) y quiero asegurarme de que el campo PersonId and Name esté SIEMPRE poblado.

public class Person
{
    int PersonId { get; set; }
    string Name { get; set; }
    string Address { get; set; }
}

Actualmente mi consulta sería

Person p = conn.Query<Person>("SELECT * FROM People");

Sin embargo, puede haber cambiado mi esquema de base de datos de PersonId a PID y ahora el código va a pasar muy bien.

Lo que me gustaría hacer es uno de los siguientes:

  1. Decore la propiedad PersonId con un atributo como Required (que dapper puede validar)

  2. Dígale a dapper que se dé cuenta de que las asignaciones no se están completando por completo (es decir, lanzar una excepción cuando todas las propiedades de la clase no se completan con los datos de la consulta).

¿Es esto posible actualmente? Si no, ¿alguien me puede indicar cómo puedo hacer esto sin afectar demasiado el rendimiento?

En mi humilde opinión , la segunda opción sería la mejor porque no romperá el código existente para los usuarios y no requiere más decoración de atributos en las clases a las que no podemos tener acceso.

Respuesta experta

Por el momento, no, esto no es posible. Y, de hecho, hay muchos casos en los que es útil llenar un modelo parcial, por lo que no quisiera agregar nada implícito . En muchos casos, el modelo de dominio es una vista ampliada del modelo de datos, por lo que no creo que la opción 2 pueda funcionar, y que se rompería en un montón de lugares en mi código; p Si nos limitamos a los más explícitos opciones ...

Hasta ahora, hemos evitado deliberadamente cosas como atributos; la idea ha sido mantener es lo más ágil y directo posible. No me opongo patológicamente a los atributos, simplemente: puede ser problemático tener que sondearlos. Pero tal vez es el momento ... también podríamos permitir el mapeo simple de columnas al mismo tiempo, es decir,

[Map(Name = "Person Id", Required = true)]
int PersonId { get; set; }

donde tanto el Name como el Required son opcionales. ¿Pensamientos? Sin embargo, esto es problemático de varias maneras, en particular en este momento solo buscamos las columnas que podemos ver , en particular en la API de extensibilidad.

La otra posibilidad es una interfaz que verifiquemos, que le permita verificar manualmente los datos después de la carga; por ejemplo:

public class Person : IMapCallback {
    void IMapCallback.BeforePopulate() {}
    void IMapCallback.AfterPopulate() {
        if(PersonId == 0)
            throw new InvalidOperationException("PersonId not populated");
    }
}

La opción de interfaz me hace más feliz de muchas maneras:

  • evita una gran cantidad de pruebas de reflexión adicionales (solo una comprobación)
  • es más flexible, puedes elegir lo que es importante para ti
  • no afecta la API de extensibilidad

pero: es más manual.

Estoy abierto a la entrada, pero quiero asegurarme de que lo hagamos bien en lugar de apresurarnos con todas las armas encendidas.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué