2012-04-18 40 views
10

Tôi hiện đang xây dựng một truy vấn SELECT nối 12 bảng với nhau. Tôi đã sử dụng Dapper cho tất cả các truy vấn khác của tôi và nó hoạt động rất tốt. Vấn đề là, các phương pháp chung chỉ có năm tham số chung.Sử dụng Dapper để ánh xạ hơn 5 loại

Tôi đã sửa đổi mã trước đó để hỗ trợ tối đa 6 cho một truy vấn khác, nhưng bây giờ tôi thực sự không nghĩ mình nên hack thêm 6 cấp generics nữa.

Có cách nào để truyền một mảng các loại và nó trả về kết quả dưới dạng một mảng các đối tượng mà tôi có thể truyền theo cách thủ công nếu tôi phải không?

Tôi cũng có thể đang tiếp cận vấn đề theo cách sai! Bất kỳ trợ giúp sẽ được đánh giá cao!

Trả lời

19

Trong một dự án tôi đã làm việc trên, tôi thấy một cái gì đó như thế này để có được hơn 7 loại ánh xạ. Chúng tôi đã sử dụng Dapper 1.38:

connection.Query<TypeOfYourResult> 
(
    queryString, 
    new[] 
    { 
     typeof(TypeOfArgument1), 
     typeof(TypeOfArgument2), 
     ..., 
     typeof(TypeOfArgumentN) 
    }, 
    objects => 
    { 
     TypeOfArgument1 arg1 = objects[0] as TypeOfArgument1; 
     TypeOfArgument2 arg2 = objects[1] as TypeOfArgument2; 
     ... 
     TypeOfArgumentN argN = objects[N] as TypeOfArgumentN; 

    // do your processing here, e.g. arg1.SomeField = arg2, etc. 
    // also initialize your result 

    var result = new TypeOfYourResult(...) 

    return result; 
    }, 
    parameters, 
    splitOn: "arg1_ID,arg2_ID, ... ,argN_ID" 
); 

QueryString tự giải thích. Tham số splitOn cho biết cách Dapper nên tách các cột khỏi câu lệnh SELECT sao cho mọi thứ có thể được ánh xạ chính xác đến các đối tượng, you can read about it here.

+3

Đánh dấu đây là câu trả lời vì đây là câu trả lời được cập nhật nhất! Điều này sẽ làm việc hoàn hảo trong trường hợp sử dụng của tôi 3 năm trước! (thời gian trôi qua!) –

+0

tuyệt vời để có câu trả lời này! – noobed

+0

Hallelujah! : D Cảm ơn Mister @Radek –

3

Bạn có thể sử dụng truy vấn động và ánh xạ nó sau đó. Một cái gì đó như thế này

var result = conn.Query<dynamic>(query).Select(x => new Tuple<Type1, Type2, Type3, Type4, Type5>( 
// type initialization here 
    new Type1(x.Property1,x.Property2), 
    new Type2(x.Property3,x.Property4), 
    new Type3(x.Property5,x.Property6) etc....)); 

Chỉnh sửa: Với một tập hợp khá lớn, một tùy chọn khác có thể là sử dụng nhiều truy vấn và sau đó sử dụng Trình đọc lưới. Điều đó có thể làm việc cho bạn.

Có ví dụ lấy từ độ tuổi hoạt bát:

var sql = 
@" 
select * from Customers where CustomerId = @id 
select * from Orders where CustomerId = @id 
select * from Returns where CustomerId = @id"; 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId})) 
{ 
    var customer = multi.Read<Customer>().Single(); 
    var orders = multi.Read<Order>().ToList(); 
    var returns = multi.Read<Return>().ToList(); 
    ... 
} 
+0

Tôi đã xem xét nó. Nhưng tôi có ~ 87 cột để lập bản đồ. Và bản đồ truy vấn của tôi hoàn toàn phù hợp với đối tượng của tôi. Khu nghỉ mát cuối cùng của tôi là bản đồ thủ công, nhưng nếu không, tôi rất muốn không loại bỏ tất cả các cột: P –

+1

Tôi thấy, bạn có thể muốn xem xét tùy chọn Lưới đọc - xem chỉnh sửa của tôi :) – Alex

+0

Sẽ không muốn chạy nhiều truy vấn khi một người thực hiện lừa. Nhưng cảm ơn sự giúp đỡ :) –

2

này đã được trả lời thời gian dài trước đây, nhưng tôi muốn thêm hai xu của tôi ở đây. Thay vì tự sửa đổi mã nguồn của Dapper, tại sao bạn không chỉ tạo một lớp poco với các trường đó và sử dụng truy vấn của bạn như một bảng?

Việc lập bản đồ sẽ hoạt động tốt, tôi biết đó cũng là một nỗi đau khi thực hiện định nghĩa lớp đó, nhưng có vẻ dễ dàng hơn là xử lý các cập nhật của Dapper sau này.

+0

Mã này đã hoàn toàn chết ngay bây giờ (và đã mở mã nguồn: https://bitbucket.org/cdroulers/invup). Nhưng tôi có thể sử dụng nó cho một dự án khác sau đó. Cảm ơn câu trả lời! –

Các vấn đề liên quan