dapper PropInfo abstract 클래스 참조로부터 상속받은 EntitySet의 Setter가 null입니다.

.net abstract-class c# dapper reflection

문제

나는 성가신 LINQ 2 SQL을 성능 향상을 위해 몇 가지 쿼리로 대체하려고합니다. 그렇게함으로써 나는 ASN 정보에 필요한 모든 정보를 보유하기 위해 필요한 큰 객체를 생성하기 위해 서로 다른 객체들을 묶어야한다.

현재 가지고있는 문제는 추상 클래스 Orders를 사용하는 것입니다.이 클래스는 discriminator 속성을 사용하는 두 개의 별도 클래스 인 AutionOrder 및 MerchantOrder에 의해 구현됩니다.

내가 추상 클래스 인 객체를 만드는 데 dapper를 사용할 수 없기 때문에 나는 대신 public 클래스 중 하나를 사용하고 있습니다. GetSettableProps 내부에서 실패 할 개체를 생성 할 때 적절한 DeclaringType 찾고 있지만 GetProperty 메서드는 internal 또는 EntitySet 속성을 찾을 때 null을 반환합니다. 내가 사용하여 주위에 해킹을 시도했습니다 t.BaseType.GetProperty 뿐만 아니라 p.GetAccessors().First().GetBaseDefinition().DeclaringType.GetProperty(p.Name).GetSetMethod(true) 성공하지 못했다.

더미 객체 :

주문

주문 ID, 이름, 주소, 행 버전 (내부), 발송물 (EntitySet), 주문 세부 정보 (EntitySet), 고객 (EntityRef)

선적

ShipmentID, OrderID, TrackingNumber

주문 세부 정보

OrderDetailID, 주문 ID, 제품, 수량, 가격

고객

고객 ID, 이름,

이 특정 SQL 히트에 대해 필자는 필요한 1 대 1 관계 매핑 중 일부를 얻으려고합니다.

o. *를 Orders에서 선택하여 왼쪽에 o와 같이 고객을 가입시킵니다 .CustomerID = c.CustomerID o.OrderID in (1,2,3);

이것은 내가 위태로운 것을 이용하기 위해 그것을 사용하고 있으며 그것이 마술을하도록합니다 :

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

Order를 public class로 변경하면이 문제는 사라지지만, 이것은 바람직한 부작용이 아닙니다. RowVersion에 propInfo를 설정하려고 할 때 실패합니다. 원하지 않더라도 내부 문제가 아니라 내부로 공용으로 전환합니다. 그러나 주문을 위해 Shipments 객체를 만들려고 할 때 실패합니다. 이번에도 Order가 공용 클래스 인 경우 아무런 문제가 없습니다.

또한 Order to Shipment와 OrderDetails to Orders와 같은 Many to One 관계를 끌어 들이고 결과를 적절한 Order Object로 정규화하는 별도의 쿼리를 수행하고 있습니다. MerchantOrder는 실제 특별한 로직이없는 빈 클래스입니다. 여기서 차별화되는 점은 실제 SQL 충돌 이전에 추상화 된 CustomerID를 찾는 것입니다.

또한 12/20/2011 현재 dapper의 최신 버전을 사용 중입니다.

나는 정말 멋져요,하지만이 문제는 내 머리가 asplode하게 - 그래서 도움을 주셔서 감사합니다!

수락 된 답변

이것은 트렁크에 수정 된 버그였습니다.

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?

한 가지 중요한 점은 디자인 상 기본 클래스에 개인 필드 나 속성을 설정하지 않는다는 것입니다. 행동은 마술적이고 일관성이 없습니다.

예 :

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?

우리는 "어느 쪽도 설정하지 말고"


인기 답변

나는 당신의 코드를 수정하지 않고 (추상적 인 클래스 때문에) 불가능하다고 생각한다.

비슷한 문제가 생겨서 추상 기본 클래스에서 파생 된 리포지토리가있는 어셈블리에 새로운 개체가 생성되었습니다.

이 클래스는 추상 클래스가 아니고 데이터를 저장하는 리포지토리 클래스에서만 볼 수 있습니다.이 클래스는 실제 테이블에 필요한 모든 메서드를가집니다.




아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.