2012-03-01 34 views
10

Tôi vừa mới bắt đầu làm việc với Dapper và tôi dường như không tìm thấy cái gì đó rất đơn giản như lập bản đồ một thực thể để một bảng trong cơ sở dữ liệu của tôi:Mapping thực thể trong Dapper

Tôi có một thủ tục lưu trữ:

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

end 
go 

Sau đó, một thực thể:

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

Và một truy vấn đoan trang trong mã của tôi:

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

Câu hỏi của tôi là: Làm thế nào tôi có thể nói với thực thể của tôi Người dùng mà Id là Userid trên cơ sở dữ liệu của tôi?

Trong EF tôi sẽ làm một cái gì đó như thế này:

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

Làm thế nào có thể ở trên đạt được trong hoạt bát?

Trả lời

15

Dapper cố tình không có một lớp bản đồ; đó là mức tối thiểu tuyệt đối có thể hoạt động, và thẳng thắn bao gồm phần lớn các tình huống thực tế trong quá trình này. Tuy nhiên, nếu tôi hiểu đúng mà bạn không muốn bí danh trong TSQL, và không muốn bất kỳ thuộc tính pass-thru - sau đó sử dụng phi 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(); 

hoặc có lẽ đơn giản hơn trong trường hợp của một hồ sơ duy nhất:

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

Bí quyết ở đây là việc không chung Query(...) API sử dụng dynamic, cung cấp lên thành viên cho mỗi tên cột.

+0

Có ảnh hưởng đến hiệu suất thực hiện theo cách này không? –

+2

@david không theo cách vật chất, có thể chậm hơn 2% –

3

Không thể, lớp người dùng của bạn phải được xác định để khớp với kết quả quay lại từ truy vấn.

Một khi bạn đã có kết quả phía sau bạn phải ánh xạ nó bằng tay đến lớp khác (hoặc sử dụng AutoMapper)

1

Bạn có thể thử một cái gì đó như thế này:

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 
} 

Nó có thể là quá mức cần thiết ví dụ của bạn, nhưng tôi đã tìm thấy nó hữu ích trong một số trường hợp để tránh làm lộn xộn mỗi Query <> gọi với mã Remapping.

+0

Muốn xử lý ánh xạ này trong mã Query <> hơn là làm lộn xộn đối tượng của tôi và buộc chúng vào lớp dữ liệu –

0

Tôi muốn giới thiệu NReco cho bạn. Nó có hiệu suất giống như người lập bản đồ nhưng với ánh xạ dễ dàng với các thuộc tính. nreco