Dapper - Multi Mapping mit einem einzigen Rückgabewert

dapper

Frage

Unten ist der Code, den ich verwende, um eine ausgelagerte Liste von Objekten zurückzugeben:

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

Obwohl das funktioniert, bedeutet das, dass ich meine Kriterien zweimal definieren muss, einmal für die Zählungsabfrage und einmal für die Ergebnismengenabfrage. Anstatt String-Verkettung zu verwenden, kann ich nur eine Abfrage ausführen:

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

Jedoch scheint ich nicht in der Lage zu sein, dies mit Dapper abzubilden. Ich kann nicht die gleiche Methode wie oben verwenden, da es nicht mehrere Ergebnisse gibt. Ich habe versucht, Multi-Mapping zu verwenden, aber dies erwartet ein IEnumerable zurückzugeben.

Wie würde ich dem Folgenden zuordnen?

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

Vielen Dank

Ben

Akzeptierte Antwort

Nun ... du würdest nicht ...

Sie müssten Ihr PostModel so anpassen, dass es eine TotalCount-Eigenschaft enthält ... was wirklich hässlich ist. Oder führe eine Dynamik aus und ordne sie in eine Select die auch hässlich ist.

Sie sehen, Sie geben Count (*) N-mal mit count(*) over() ... es ist ein Hack, mit diesem Hack ist nicht unbedingt schneller. Ich habe gemessen, dass es in einigen meiner Szenarien langsamer als das Ausführen einer doppelten Abfrage ist, insbesondere können Sie einige Indizes in der select count(*) abkürzen, da Sie nicht alle Spalten auswählen. Darüber hinaus deaktiviert der Hack bestimmte Paging-Optimierungen, z. B. können Sie der Abfrage kein select top N hinzufügen.

Meine Empfehlung bei Paging-Abfragen wäre, die Indizierung richtig zu machen, das ist der Schlüssel. Messen Sie perf und sehen Sie, ob dieser Hack tatsächlich hilft (wenn die korrekte Indizierung vorhanden ist).

Ich folge den Bedenken bezüglich der String-Verkettung, aber Sie können immer allgemeine Hilfsmethoden dafür definieren.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow