Dapper - 単一の戻り値を持つマルチマッピング

dapper

質問

以下は、オブジェクトのページリストを返すために使用しているコードです:

string query2 = @"
        select count(*) as TotalCount from blogposts p where p.Deleted = 0 and p.PublishDate <= @date
        select * from (
            select p.*, 
            row_number() over(order by publishdate desc) as rownum
            from blogposts as p
            where p.Deleted = 0 and p.PublishDate <= @date
        ) seq
        where seq.rownum between @x and @y";

using (var cn = new SqlConnection(connectionString))
{
    cn.Open();
    using (var multi = cn.QueryMultiple(query2, new { x= lower, y = upper, date = DateTime.UtcNow }))
    {
        var totalCount = multi.Read<int>().Single();
        var posts = multi.Read<PostModel>().ToList();
        return new PagedList<PostModel>(posts, page, pageSize, x => totalCount);
    }
}

これは機能しますが、基準を2回、カウントクエリに対して1回、結果セットクエリに対して1回定義する必要があることを意味します。文字列の連結に頼るのではなく、ただ1つのクエリを実行できます。

        string query = @"
                select * from (select p.*, 
                row_number() over(order by publishdate desc) as rownum,
                count(*) over() as TotalCount
                from blogposts as p) seq
                where seq.rownum between @x and @y";

しかし、私はこれをDapperを使ってマップすることはできないようです。複数の結果がないため、上記と同じ方法を使用することはできません。私はマルチマッピングを使用しようとしましたが、これはIEnumerableを返すことを期待しています。

私はどのようにして次のようにマップしますか?

    public class PostList
    {
        public IEnumerable<PostModel> Posts;
        public int TotalCount { get; set; }
    }

ありがとう

ベン

受け入れられた回答

まあ...あなたは...

あなたはあなたのPostModelにTotalCountプロパティを含めるように修正する必要があります。これは本当に醜いです。または、動的に実行し、 Selectで再マッピングします。これは醜いものです。

あなたは、count(*)をN回count(*)に戻しています(... count(*) over() 。これはハックですが、このハックを使うのは必ずしも高速ではありません。私はいくつかのシナリオでダブルクエリを実行するよりも遅いと評価しました。特に、すべての列を選択していないので、 select count(*)インデックスをショートカットできます。さらに、ハッキングは特定のページングの最適化を無効にします。たとえば、 select top Nselect top Nしてクエリに追加select top Nことはできません。

ページングクエリに関する私の推奨は、インデックス作成を正しく行うことです。それは重要です。 perfを測定し、このハッキングが実際に役立つかどうかを確認します(正しいインデックスが設定されている場合)。

私は文字列の連結に関する懸念については従っていますが、そのために一般的なヘルパーメソッドを定義することはいつでも可能です。



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ