3 단계 딥 매핑을 사용하여 Dapper에서 다중 매핑 쿼리를 만드는 방법은 무엇입니까?

c# dapper

문제

다음을 올바르게 매핑하는 쿼리를 수행하려고합니다.

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int BId {get; set; }
    public List<B> { get; set; }
}

public class B
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CId { get; set; }
    public int DId { get; set; }
    public C C { get; set; }
    public D D { get; set; }
}

public class C
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class D
{
    public int Id { get; set; }
    public string Name { get; set; }
}

C와 D가 채워진 엔티티 B의 목록으로 엔티티 A를 올바르게 매핑하는 쿼리를 작성하려면 어떻게해야합니까?

수락 된 답변

A에서 B의 일대 다 특성을 캡처하기 위해 여기 두 가지 쿼리를 수행하려고합니다. 또한 B는 아마도 쿼리에서 A에 대한 참조를 다시 필요로 할 것입니다.

var query1 = conn.Query<A>(select * from dbo.A)

var query2 = conn.Query<B,C,D,B>("select * from dbo.B...join C...join 

D",(b,c,d)=>{



     b.C = c;
        b.D = d;

return b;

        }

이제는 서로 연결해야합니다. 나는 linq 조인과 확장을 사용하여 여러 항목을 자동화하지만 요점은 각 'A'를 반복하고 쿼리 2에서 일치하는 'B'를 찾습니다. 사전과 목록은 'Where'절보다 빠르며 아래 루프를 최적화하는 확장을 작성할 수 있습니다.

foreach(var a in query1){
a.Bs = query2.Where(w=>w.AId.Equals(a.Id));
}

여러 레코드 집합을 반환하려면 QueryMultiple을 사용하여 db 이동을 줄일 수 있습니다 (db가 지원해야 함).


인기 답변

Drapper (Dapper의 상단에 구축 됨)를 사용하여 db에 대한 한 번의 왕복으로 아마 달성 할 수 있습니다.

여러 결과를 반환하는 SQL 쿼리 집합이 있다고 가정합니다.

select * from [TableA]; 
select * from [TableB]; 
select * from [TableC]; 
select * from [TableD]

... 각 결과가 다른 형식의 식별자 / 외래 키의 일부 형식을 보유하고 있으면 다음과 같은 저장소를 구축 할 수 있습니다.

public class Repository : IRepository
{
    // IDbCommander is a Drapper construct.
    private readonly IDbCommander _commander;

    public Repository(IDbCommander commander)
    {
        _commander = commander;
    }

    public IEnumerable<A> RetrieveAll()
    {
        // execute the multiple queries and 
        // pass control to a mapping function.
        return _commander.Query(Map.Results);
    }

    private static class Map
    {
        internal static Func<IEnumerable<A>,
                            IEnumerable<B>,
                            IEnumerable<C>,
                            IEnumerable<C>,
                            IEnumerable<A>> Results = (collectionA, collectionB, collectionC, collectionD) => 
        {
            // map C and D to B based on their Id's
            collectionB.C = collectionC.SingleOrDefault(c => c.Id == b.Id);
            collectionB.D = collectionD.SingleOrDefault(d => d.Id == b.Id);

            // now map B to A.
            collectionA.B = collectionB.Where(b => b.Id == a.Id).ToList();
            return collectionA;
        }
    }
}

예를 들어 메모리에서 입력하면 구문이 다소 벗어날 수 있지만 요지는 얻을 수 있습니다.

나는 BlackjacetMack에 동의한다. 당신은 결과에 페이지 매김을해야한다. (Drapper에서도 지원된다.)



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow