Entidad de Mapeo en Dapper
Pregunta
Acabo de empezar a trabajar con Dapper y no parece encontrar algo muy simple como mapear una entidad a una mesa en mi base de datos:
Tengo un procedimiento almacenado:
CREATE PROCEDURE [dbo].GetUserById (@UserId int)
AS
begin
SELECT UserId,LastName,FirstName,EmailAddress
FROM users
WHERE UserID = @UserId
end
go
entonces una entidad:
public class User
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
}
y una consulta DAPPER en mi código:
int userid=1;
User User = connection.Query<User>("#GetUserById", new {userid=userid}, commandType: CommandType.StoredProcedure).FirstOrDefault();
Mi pregunta es: ¿Cómo puedo decirle al usuario de mi entidad que ID está userid en mi base de datos?
En EF, haría algo así:
MapSingleType(c => new
{
UserId = c.Id,
Firstname = c.Firstname,
Lastname = c.Lastname,
EmailAddress = c.Email
}).ToTable("users");
¿Cómo se puede lograr lo anterior en DAPPER?
Solución
Dapper deliberately doesn't have a mapping layer; it is the absolute minimum that can work, and frankly covers the majority of real scenarios in the process. However, if I understand correctly that you don't want to alias in the TSQL, and don't want any pass-thru properties - then use the non-generic Query
API:
User user = connection.Query("...", ...).Select(obj => new User {
Id = (int) obj.UserId,
FirstName = (string) obj.FirstName,
LastName = (string) obj.LastName,
Email = (string) obj.EmailAddress
}).FirstOrDefault();
or perhaps more simply in the case of a single record:
var obj = connection.Query("...", ...).FirstOrDefault();
User user = new User {
Id = (int) obj.UserId,
FirstName = (string) obj.FirstName,
LastName = (string) obj.LastName,
Email = (string) obj.EmailAddress
};
The trick here is that the non-generic Query(...)
API uses dynamic
, offering up members per column name.
Otros consejos
It can't, your user class must be defined to match the result coming back from the query.
Once you've got the result back you must map it manually to another class (or use AutoMapper)
You could try something like this:
public class User
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
#region Remappings
public int UserId
{
get { return Id; }
set { Id = value; }
}
#endregion
}
It might be overkill for your example, but I've found it useful in some situations to avoid cluttering every Query<> call with the remapping code.
I would recommend NReco to you. It is performant like dapper but with easy mapping with attributes. nreco