Mapeamento de entidade no Dapper
Pergunta
Eu apenas comecei a trabalhar com o Dapper e eu não consigo encontrar algo muito simples, como o mapeamento de uma entidade para uma tabela no meu banco de dados:
Eu tenho um procedimento armazenado:
CREATE PROCEDURE [dbo].GetUserById (@UserId int)
AS
begin
SELECT UserId,LastName,FirstName,EmailAddress
FROM users
WHERE UserID = @UserId
end
go
Em seguida, uma entidade:
public class User
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
}
E um dapper consulta no meu código:
int userid=1;
User User = connection.Query<User>("#GetUserById", new {userid=userid}, commandType: CommandType.StoredProcedure).FirstOrDefault();
A minha pergunta é:Como posso saber a minha entidade Usuário que Id é o id de utilizador no meu banco de dados?
Em EF gostaria de fazer algo como isto:
MapSingleType(c => new
{
UserId = c.Id,
Firstname = c.Firstname,
Lastname = c.Lastname,
EmailAddress = c.Email
}).ToTable("users");
Como pode o acima ser alcançado no dapper?
Solução
Dapper, deliberadamente, não tem uma camada de mapeamento;é o mínimo que se pode trabalhar, e, francamente, cobre a maioria dos cenários reais no processo.No entanto, se compreendo corretamente o que você não quer alias em TSQL, e não querem qualquer pass-thru propriedades - em seguida, use o genérico não 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();
ou talvez mais simplesmente, no caso de um único registro:
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
};
O truque aqui é que o genérico não Query(...)
API usa dynamic
, oferecendo membros por nome de coluna.
Outras dicas
Ele não pode, de sua classe de usuário deve ser definido para coincidir com o resultado de voltar da consulta.
Uma vez que você tenha o resultado que você deve mapear manualmente para outra classe (ou usar o AutoMapper)
Você pode tentar algo como isto:
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
}
Ele pode ser um exagero para o seu exemplo, mas eu descobri que é útil em algumas situações para evitar sobrecarregar a cada Consulta<> chamada com o remapeamento de código.
Eu recomendaria NReco para você.É a performance como dapper, mas com fácil mapeamento de atributos.nreco