18

Dapperで遊んで、これまでの結果に非常に満足しています-興味をそそられます!

Studentしかし今、私の次のシナリオは、2つのテーブル(aとテーブル)からデータを読み取ることAddressです。

Studentテーブルの主キーは、、StudentID (INT IDENTITY)です。テーブルへのリンクと呼ばれるFKもあります。AddressAddressID (INT IDENTITY)StudentAddressIDAddress

私のアイデアは、関心のあるプロパティを使用して、テーブルごとに1つずつ、2つのクラスを作成することでした。さらに、C#のクラスにPrimaryAddresstypeのプロパティをAddress配置しました。Student

次に、1つのクエリで学生と住所の両方のデータを取得しようとしました-Githubページにあるサンプルを模倣します:

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

ここで、aPostとaUserが取得され、投稿の所有者がユーザーに設定されます-返されるタイプはPost-正しいですか?

したがって、私のコードでは、汎用Query拡張メソッドに2つのパラメーターを定義します。1つStudent目は返される必要がありAddress、2つ目はstudentインスタンスに格納されます。

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

問題は-VisualStudioでエラーが発生します:

一般的なメソッド'Dapper.SqlMapper.Query(System.Data.IDbConnection、string、System.Func、dynamic、System.Data.IDbTransaction、bool、string、int?、System.Data.CommandType?)'を使用するには、6つの型引数が必要です。

Dapperが6つの型引数でこのオーバーロードを使用することを主張する理由を私は本当に理解していません...

4

1 に答える 1

23

これは、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");

}

Dapper はすべてのマルチ マッピング API を 1 つのメソッドでパイプ処理するため、何かが失敗した場合は 6 パラメーターの 1 つになります。パズルのもう 1 つのピースは、追加したばかりの非常に柔軟な分割を許可しなかったことです。

splitOnパラメータのデフォルトはであることに注意してください。つまり、最初のオブジェクト境界としてorIdと呼ばれる列を使用します。ただし、「3 方向」マルチ マッピングなどの異なる名前を持つ複数の主キーの境界が必要な場合は、カンマ区切りのリストを渡すことができるようになりました。idId

したがって、上記を修正する場合、おそらく次のようになります。

 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();
于 2011-05-14T12:43:46.803 に答える