2011-05-14 6 views
16

Dapper를 가지고 놀면서, 지금까지의 결과에 매우 만족합니다!Dapper에서 멀티 맵핑을 사용할 수 없습니다.

하지만 지금은 두 테이블 (StudentAddress 테이블)에서 데이터를 읽는 것이 좋습니다.

Student 테이블의 기본 키가 StudentID (INT IDENTITY)이고 AddressAddressID (INT IDENTITY)입니다. Student에는 테이블로 연결되는 AddressID이라는 FK도 있습니다.

나의 생각은 내가 관심이있는 속성으로, 두 개의 클래스, 각 테이블을 만드는 것이 었습니다. 또한, 나는 C#에서 내 Student 클래스에 유형 AddressPrimaryAddress 속성을 넣어.

나는 다음 단일 쿼리 모두 학생 및 주소 데이터를 검색하려고 - 나는이 (가) Github page에 주어진 것 샘플 해내는 : 여기

var data = connection.Query<Post, User>(sql, (post, user) => { post.Owner = user; }); 
var post = data.First(); 

하는 PostUser를 검색하고, 소유자를 게시물이 사용자에게 설정됩니다. 반환되는 유형은 Post입니다. 맞습니까?

var student = _conn.Query<Student, Address> 
        ("SELECT s.*, a.* FROM dbo.Student s 
         INNER JOIN dbo.Address a ON s.AddressID = a.AddressID 
         WHERE s.StudentenID = @Id", 
        (stu, adr) => { stu.PrimaryAddress = adr; }, 
        new { Id = 4711 }); 
: 리턴 된 첫 번째로 Student, 두 번째로 Address, 학생 인스턴스에 저장됩니다 -

그래서 내 코드에서 나는 일반 Query 확장 메서드에 두 개의 매개 변수를 정의

문제는 - 내가 Visual Studio에서 오류 얻을 : 일반적인 방법 'Dapper.SqlMapper.Query를 사용

을 (System.Data.IDbConnection, 문자열 System.Func, 동적, System.Data.IDbTransaction, 부울, 문자열, INT? System.Data.CommandType은?) '6 개 형태 인수를

난 정말 이유를 단정을 이해하지 못하는이 필요 이 오버로드를 6 가지 형식의 인수로 사용하는 것을 주장합니다 ...

+2

나는 똑같은 문제를 겪고과 이유를 알아낼 걸 렸어요 - 샘이 설명으로! –

답변

21

API를 변경하고 설명서를 업데이트하지 않아서 오류가 수정되었습니다.

전체 사양을 보려면 Tests.cs을 확인하십시오.

특히 이전 API는 매핑을 수행하기 위해 Action<T,U>을 사용했지만 문제는 임의적이며 융통성이 없다는 것입니다. 반환 유형을 완전히 제어 할 수 없습니다. 새 API는 Func<T,U,V>을 사용합니다. 따라서 매퍼에서 반환하는 유형을 제어 할 수 있으며 매핑 된 유형 일 필요는 없습니다.

난 그냥 멀티 매핑 주위에 약간의 유연성을 이끌어 냈습니다

은,이 테스트는 명확하게해야합니다

class Person 
{ 
    public int PersonId { get; set; } 
    public string Name { get; set; } 
} 

class Address 
{ 
    public int AddressId { get; set; } 
    public string Name { get; set; } 
    public int PersonId { get; set; } 
} 

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

public void TestFlexibleMultiMapping() 
{ 
    var sql = 
@"select 
1 as PersonId, 'bob' as Name, 
2 as AddressId, 'abc street' as Name, 1 as PersonId, 
3 as Id, 'fred' as Name 
"; 
    var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address,Extra>> 
     (sql, (p,a,e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First(); 

    personWithAddress.Item1.PersonId.IsEqualTo(1); 
    personWithAddress.Item1.Name.IsEqualTo("bob"); 
    personWithAddress.Item2.AddressId.IsEqualTo(2); 
    personWithAddress.Item2.Name.IsEqualTo("abc street"); 
    personWithAddress.Item2.PersonId.IsEqualTo(1); 
    personWithAddress.Item3.Id.IsEqualTo(3); 
    personWithAddress.Item3.Name.IsEqualTo("fred"); 

} 

말끔 파이프 모든 다중 매핑 API를 하나의 방법으로, 무언가가 실패 할 경우이에 끝날 수 있도록 6 param one.퍼즐의 다른 부분은 제가 방금 추가 한 유연한 스플릿을 허용하지 않았다는 것입니다.

참고 : splitOn 매개 변수의 기본값은 Id입니다. 즉, id 또는 Id이라는 열을 첫 번째 개체 경계로 사용합니다. 그러나 "3 방향"다중 매핑에 대해 다른 이름을 가진 여러 기본 키에 경계가 필요한 경우 이제 쉼표로 구분 된 목록을 전달할 수 있습니다.

우리는 위의 문제를 해결했다 그렇다면, 아마도 다음과 같은 작동합니다 :

var student = _conn.Query<Student,Address,Student> 
       ("SELECT s.*, a.* FROM dbo.Student s 
        INNER JOIN dbo.Address a ON s.AddressID = a.AddressID 
        WHERE s.StudentenID = @Id", 
       (stu, adr) => { stu.PrimaryAddress = adr; return stu;}, 
       new { Id = 4711 }, splitOn: "AddressID").FirstOrDefault(); 
+0

감사합니다.하지만 'StudentId = @ Id'와 같은 기준을 추가 한 다음 (이 경우'@ID = 4711'을)이 다중 매핑 쿼리에 추가 할 수 있습니까 ?? –

+1

@marc_s에서 편집 한 내용 ... –

+0

@marc_s에는 명령 유형, 명령 시간 초과 등을 제어하는 ​​데 필요한 옵션 매개 변수가 많이 있습니다. 하나의 중요한 배울 점은 결과를 버퍼링하여 SqlReaders가 서로 움직이지 않도록 허용하는 "버퍼링 됨"입니다. –