Сопоставление объекта в Dapper

Я только начал работать с Dapper и, похоже, не нашел чего-то очень простого, например сопоставления объекта с таблицей в моей базе данных:

У меня есть хранимая процедура:

CREATE PROCEDURE [dbo].GetUserById (@UserId int)
AS  
begin               
        SELECT UserId,LastName,FirstName,EmailAddress
        FROM users
        WHERE UserID = @UserId

end
go

Затем сущность:

public class User
{
    public int Id { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Email { get; set; }
}

И изящный запрос в моем коде:

int userid=1;
    User User = connection.Query<User>("#GetUserById", new {userid=userid}, commandType: CommandType.StoredProcedure).FirstOrDefault();

Мой вопрос: как я могу сообщить моему юзеру, что Id - это Userid в моей базе данных?

В EF я бы сделал что-то вроде этого:

MapSingleType(c => new
            {
                UserId = c.Id,
                Firstname = c.Firstname,
                Lastname = c.Lastname,
                EmailAddress = c.Email
            }).ToTable("users");

Как можно добиться вышеперечисленного в dapper?


person David Aleu    schedule 01.03.2012    source источник


Ответы (4)


Dapper намеренно не имеет слоя отображения; это абсолютный минимум, который может работать, и, честно говоря, покрывает большинство реальных сценариев в процессе. Однако, если я правильно понимаю, что вы не хотите использовать псевдоним в TSQL и не хотите никаких сквозных свойств, тогда используйте необщий 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();

или, возможно, проще в случае одной записи:

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
};

Хитрость здесь в том, что неуниверсальный Query(...) API использует dynamic, предлагая элементы для каждого имени столбца.

person Marc Gravell    schedule 01.03.2012
comment
@david не материально, может на 2% медленнее - person Sam Saffron; 02.03.2012

Это невозможно, ваш пользовательский класс должен быть определен так, чтобы соответствовать результату, возвращаемому из запроса.

Как только вы получите результат, вы должны вручную сопоставить его с другим классом (или использовать AutoMapper)

person ilivewithian    schedule 01.03.2012

Вы можете попробовать что-то вроде этого:

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
}

Это может быть излишним для вашего примера, но я нашел полезным в некоторых ситуациях не загромождать каждый вызов Query‹> кодом переназначения.

person Russ    schedule 29.08.2012
comment
Предпочел бы обрабатывать это сопоставление в коде Query‹›, чем загромождать мои объекты и привязывать их к слою данных - person Karl Glennon; 22.10.2012

Я бы порекомендовал вам NReco. Он эффективен, как dapper, но с простым сопоставлением с атрибутами. nreco

person Franki1986    schedule 06.11.2016