Dapper 쿼리를 객체 컬렉션에 매핑 (컬렉션 자체가 두 개 있습니다)

dapper multi-mapping

문제

단일 쿼리 (또는 여러 결과 집합이있는 저장 프로 시저)를 실행하려고합니다. Dapper를 사용하여 다중 매핑을 수행하는 방법을 알고 있지만 동일한 부모에 두 컬렉션을 매핑하는 방법을 정렬 할 수 없습니다. 기본적으로이 Object 정의가 주어진다면 ...

IQueryable<ParentObject> result = cnn.Query(
          // Some really awesome dapper syntax goes here
);

어떻게 든 Dapper 쿼리를 실행할 수 있기를 원합니다.

IQueryable<ParentObject> result = cnn.Query(
          // Some really awesome dapper syntax goes here
);

수락 된 답변

멀티 맵핑을 사용하고 싶지는 않지만 귀하의 경우에 어떻게 작동되는지는 확실하지 않습니다. 지금까지 내가 알고 있고 읽었던 것처럼 간단한 중첩 된 개체 그래프를 간단한 Query 로 매핑 할 수는 없습니다.

 static void Main(string[] args)
        {
            var sqlParent = "SELECT parentId as Id FROM ParentTable WHERE parentId=1;";
            var sqlChildOneSet = "SELECT Name FROM ChildOneTable;"; // Add an appropriate WHERE
            var sqlChildTwoSet = "SELECT Id, LocationName FROM ChildTwoTable;"; // Add an appropriate WHERE

            var conn = GetConnection() // whatever you're getting connections with
            using (conn)
            {
                conn.Open();
                using (var multi = conn.QueryMultiple(sqlParent + sqlChildOneSet + sqlChildTwoSet))
                {
                    var parent = multi.Read<ParentObject>().First();
                    parent.ChildSetOne = multi.Read<ChildOne>().ToList();
                    parent.ChildSetTwo = multi.Read<ChildTwo>().ToList();
                }
            }
        }

중첩 된 객체와 dapper에 대한 비슷한 질문 :

https://stackoverflow.com/search?q=nested+objects+%2B+dapper


인기 답변

IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map); 사용하여 일대 다 관계를 갖는 객체를 IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map); 메소드를 호출합니다. 그러나 엔티티에 대해 몇 가지 사항을 변경하여 충분한 정보를 얻을 수 있어야합니다.

다음은 유사한 질문이있는 몇 가지 SO 스레드입니다.

Dapper를 사용하여 중첩 된 객체의 목록을 매핑하는 방법

더 깨끗하게 만드는 확장 기능

예제를 통한 Dapper.Net - 매핑 관계

public class ParentObject
{
    public ParentObject()
    {
        ChildSetOne = new List<ChildObjectOne>();
        ChildSetTwo = new List<ChildObjectTwo>();
    }
    // 1) Although its possible to do this without this Id property, For sanity it is advisable.
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<ChildObjectOne> ChildSetOne {get; private set;}
    public ICollection<ChildObjectTwo> ChildSetTwo { get; private set; }
}

public class ChildObjectOne
{
    // 2a) Need a ParentId
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class ChildObjectTwo
{
    // 2b) This ParentId is not required but again for sanity it is advisable to include it.
    public int ParentId { get; set; }
    public int id { get; set; }
    public string LocationName { get; set; }
}

public class Repository
{
    public IEnumerable<ParentObject> Get()
    {
        string sql = 
            @"SELECT 
                p.Id, 
                p.Name, 
                o.Name, 
                o.ParentId, 
                t.Id, 
                t.LocationName, 
                t.ParentId 
            FROM 
                Parent p 
                    LEFT JOIN ChildOne o on o.ParentId = p.Id 
                    LEFT JOIN ChildTwo t on t.ParentId = p.Id 
            WHERE 
                p.Name LIKE '%Something%'";

        var lookup = new Dictionary<int, ParentObject>();
        using (var connection = CreateConnection())
        {

            connection.Query<ParentObject, ChildObjectOne, ChildObjectTwo, ParentObject>(
                sql, (parent, childOne, childTwo) =>
                {
                    ParentObject activeParent;

                    if (!lookup.TryGetValue(childOne.ParentId, out activeParent)) 
                    {
                        activeParent = parent;
                        lookup.add(activeParent.Id, activeParent);
                    }

                    //TODO: if you need to check for duplicates or null do so here
                    activeParent.ChildSetOne.Add(childOne);

                    //TODO: if you need to check for duplicates or null do so here
                    activeParent.ChildSetTwo.Add(childTwo);

                });   
        }
        return lookup.Values;
    }
}



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