Dapper - Multi Mapping с одним возвращаемым значением

Ниже приведен код, который я использую для возврата постраничного списка объектов:

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

Хотя это работает, это означает, что я должен определить свои критерии дважды, один раз для запроса подсчета и один раз для запроса набора результатов. Вместо того, чтобы прибегать к конкатенации строк, я могу выполнить только один запрос:

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

Спасибо

Бен

7 голосов | спросил Ben Foster 2 J0000006Europe/Moscow 2011, 15:49:45

1 ответ


0

Ну ... ты бы не ...

Вы должны будете изменить свой PostModel, чтобы он включал свойство TotalCount ... что действительно ужасно. Или выполните динамическое преобразование и переназначьте его в Select, что тоже ужасно.

Видите ли, вы возвращаете count (*) N раз с count(*) over() ... это взлом, использование этого взлома не обязательно быстрее. Я измерил, что это медленнее, чем выполнение двойного запроса в некоторых моих сценариях, в частности, вы можете ярлыки некоторых индексов в select count(*), так как не выбирают все столбцы. Кроме того, хак отключает некоторые оптимизации подкачки, например, вы не можете добавить select top N в запрос.

Моя рекомендация по поисковым запросам заключается в правильной индексации, это ключевой момент. Измерьте перфект и посмотрите, действительно ли этот хак помогает (при правильной индексации).

Я следую за проблемами конкатенации строк, но вы всегда можете определить общие вспомогательные методы для этого.

ответил Sam Saffron 2 J0000006Europe/Moscow 2011, 16:26:13

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132