.NET Dapper - Asignación de propiedades calculadas

.net c# dapper orm

Pregunta

Estoy usando Dapper para manejar la conexión de la base de datos en un proyecto .NET. La asignación automática de columnas funciona bien y también puedo asignar columnas a diferentes nombres de propiedad en el modelo. Sin embargo, ¿cómo puedo mapear las propiedades calculadas? Por ejemplo, mi modelo es

class User
{
    public int Id {get; set;}
    public string Name {get; set;}
    public bool IsPremiumUser {get; set;}
}

Y la mesa es

Id | Name | CreationDate | IsPremiumUser

Ahora, IsPremiumUser puede ser nulo en db pero no en el modelo. Me gustaría que se mapee con la siguiente lógica:

if (row.IsPremiumUser != null)
{
    model.IsPremiumUser = row.IsPremiumUser;
}
else
{
    model.IsPremiumUser = row.CreationDate < 1.1.2000;
}

En otras palabras, su valor depende de 2 columnas. También hay varios casos en los que me gustaría establecer una propiedad booleana en función de si existe una cierta relación. ¿Cómo manejar estos casos de mapeo más complejos?

Respuesta aceptada

Solo use la consulta SQL que verificará si el campo IsPremiumUser no es nulo y devolverá el resultado de la comprobación de la fecha de creación si el usuario no tiene este conjunto de indicadores:

var sql =
    @"SELECT 
        Id,
        Name,
        CASE
            WHEN IsPremiumUser IS NOT NULL
                THEN IsPremiumUser
                ELSE CAST(CASE WHEN CreationDate < '2000-01-01' THEN 1 ELSE 0 END AS BIT)
        END AS IsPremiumUser
        FROM Users";
var users = conn.Query<User>(sql);

Otra opción será usar una consulta dinámica con resultados de mapeo manuales para la clase de usuario:

var sql = @"SELECT Id, Name, CreationDate, IsPremiumUser FROM Users";
var millenium = new DateTime(2000, 1, 1);

var users = conn.Query(sql).Select(row => new User {
       Id = row.Id,
       Name = row.Name,
       IsPremiumUser = row.IsPremiumUser == null
           ? row.CreationDate < millenium
           : row.IsPremiumUser
    });

Respuesta popular

Otra opción es hacer una fábrica y dejar que ensamble al usuario:

var userRecords = _connection.Query<UserRecord>("select * from users");   
var users = UserFactory.Build(userRecords);
  • La clase UserRecord solo se usa para consultar los datos
  • Factory manejará la asignación de propiedades y las propiedades dinámicas

Pros: Mantenga consultas SQL libres de lógica. La fábrica es más flexible con el tiempo.

Contras: Más código



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é