2011-12-21 40 views
12

Tôi đang cố gắng thay thế một truy vấn LINQ 2 SQL khó chịu bằng một số truy vấn dapper để cải thiện performanace. Trong khi làm như vậy tôi phải dệt một loạt các đối tượng khác nhau với nhau để tạo ra các đối tượng lớn cần thiết để giữ tất cả các thông tin tôi cần cho thông tin ASN.dapper PropInfo Setter cho EntitySet kế thừa từ tham chiếu lớp trừu tượng là null

Vấn đề hiện tại tôi đang gặp là với một lớp tóm tắt Đơn đặt hàng, lớp này được thực hiện bởi hai lớp riêng biệt AutionOrder và MerchantOrder sử dụng thuộc tính phân biệt đối xử.

Vì tôi không thể sử dụng công cụ vẽ để tạo đối tượng là lớp trừu tượng, thay vào đó tôi sử dụng một trong các lớp công khai. Tuy nhiên khi nó đi để xây dựng các đối tượng nó đang thất bại bên trong của GetSettableProps nó là tìm đúng DeclaringType nhưng phương pháp GetProperty là trở về null khi nó đang tìm kiếm một tài sản là internal hoặc là một EntitySet. Tôi đã cố gắng để hack xung quanh nó bằng cách sử dụng t.BaseType.GetProperty cũng như p.GetAccessors().First().GetBaseDefinition().DeclaringType.GetProperty(p.Name).GetSetMethod(true) không thành công.

đối tượng giả:

tự

OrderID, Tên, Địa chỉ, rowversion (nội bộ), Lô hàng (EntitySet), OrderDetails (EntitySet), Khách hàng (EntityRef)

Lô hàng

Lô hàngID, Quy định erID, TRACKINGNUMBER

OrderDetails

OrderDetailID, OrderID, sản phẩm, QTY, Giá

khách hàng

CustomerID, Tên,

Đối với lần truy cập SQL cụ thể này, tôi đang cố gắng lấy một số ánh xạ mối quan hệ 1 đến 1 mà tôi cần.

CHỌN * từ Đơn đặt hàng dưới dạng o left join Khách hàng với tư cách c trên o.CustomerID = c.CustomerID trong đó o.OrderID in (1,2,3);

Đây là những gì tôi đang sử dụng để sử dụng hoạt bát và để cho nó làm điều đó là kỳ diệu:

using (var connection = new SqlConnection(_ConnectionString)) 
{ 
    connection.Open(); 
    results = connection.Query<MerchantOrder, MerchantCustomer, MerchantOrder>(sql.ToString(), 
     (o, c) => { o.Customer = c; return o; }, 
     splitOn: "CustomerID"); 
} 

Nếu tôi thay đổi thứ tự để có một lớp nào vấn đề này sẽ biến mất mặc dù, nhưng đây không phải là mong muốn tác dụng phụ. Đó là thất bại khi cố gắng đặt propInfo cho RowVersion - chuyển đổi này thành pubic thay vì nội bộ giải quyết vấn đề này - mặc dù không mong muốn. Nhưng sau đó nó không thành công khi nó đang cố gắng tạo ra các đối tượng lô hàng cho trật tự. Một lần nữa, đây không phải là vấn đề khi Order là một lớp public.

Ngoài ra tôi đang thực hiện các truy vấn riêng lẻ để kéo nhiều trong một mối quan hệ như giao hàng đến đơn đặt hàng và OrderDetails để đơn đặt hàng và chuẩn hóa kết quả vào đúng đối tượng đặt hàng. MerchantOrder là một lớp trống rỗng không có logic đặc biệt thực sự. Sự phân biệt đối xử khác nhau ở đây chỉ là cách chúng ta kết thúc việc tìm kiếm CustomerID được trừu tượng trước khi nhấn SQL thực tế.

Ngoài ra tôi đang sử dụng phiên bản mới nhất của công cụ lập bản đồ kể từ ngày 20/12/2011.

Tôi thực sự thích cáu kỉnh, nhưng vấn đề này là làm cho đầu của tôi asplode - vì vậy cảm ơn sự giúp đỡ!

+0

bạn có thể thêm một thử nghiệm thất bại vì vậy tôi có thể sửa lỗi này? chỉ cần gửi một bản vá với nó –

+0

Tôi đã thêm một thử nghiệm không thành công @ https://code.google.com/r/johnzaborow-fail-test/ Tôi đã gặp rất nhiều sự cố khi tự động đẩy các thay đổi của mình nên tôi đã từng làm một . cho tôi biết nếu có gì cần phải thay đổi. cảm ơn! – John

+0

đã được khắc phục ngay bây giờ, cảm ơn! –

Trả lời

7

Đây là một lỗi, mà bây giờ là cố định trong thân cây:

public class AbstractInheritance 
    { 
     public abstract class Order 
     { 
      internal int Internal { get; set; } 
      protected int Protected { get; set; } 
      public int Public { get; set; } 

      public int ProtectedVal { get { return Protected; } } 
     } 

     public class ConcreteOrder : Order 
     { 
      public int Concrete { get; set; } 
     } 
    } 

    // http://stackoverflow.com/q/8593871 
    public void TestAbstractInheritance() 
    { 
     var order = connection.Query<AbstractInheritance.ConcreteOrder>("select 1 Internal,2 Protected,3 [Public],4 Concrete").First(); 

     order.Internal.IsEqualTo(1); 
     order.ProtectedVal.IsEqualTo(2); 
     order.Public.IsEqualTo(3); 
     order.Concrete.IsEqualTo(4); 

    } 

Một mặt lưu ý là, theo thiết kế, chúng tôi không đặt lĩnh vực tư nhân hoặc tài sản trong các lớp cơ sở. Hành vi có thể là phép thuật và không nhất quán.

Ví dụ:

class A { private int a {get; set;} } 
class B : A { private int a {get; set;} } 
class C: B {} 

// What should "select 1 a" do? Set it on A? Set it on B? Set it on Both? Set it on neither? 

Chúng tôi đã đi với "đặt nó trên không"

+0

Cảm ơn rất nhiều vì đã sửa! Điều này khiến tôi gãi đầu một lúc! Món quà sinh nhật tốt nhất mà tôi có trong năm nay! – John

+0

không phải lo lắng, vui mừng vì nó hoạt động! –

0

Tôi nghĩ là không thể (vì lớp trừu tượng) mà không sửa đổi mã của bạn.

Tôi đã gặp sự cố tương tự và kết thúc việc tạo một đối tượng mới riêng tư cho hội đồng nơi tôi có các kho lưu trữ của tôi xuất phát từ lớp cơ sở trừu tượng.

Lớp này là không trừu tượng và chỉ hiển thị cho lớp lưu trữ lưu trữ dữ liệu, lớp này có tất cả các phương thức được yêu cầu cho bảng thực tế.

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