Paged, Multi-Poco queries with Petapoco?

老子叫甜甜 提交于 2019-12-22 10:33:38

问题


PetaPoco is great and covers paged queries and Multi-Poco mapping, but I'm trying to figure out if there's a way to do them together?

Edit:

Here's the repository method I use to get MultiPoco data:

// variables, used in multiple repo methods
private readonly string _selectClause = String.Format(@"SELECT * FROM Clients 
                                                                    OUTER APPLY 
                                                            (SELECT TOP 1* From Events 
                                                                 WHERE Events.EndDateTime >= '{0}'
                                                                 AND Events.ClientId = Clients.Id
                                                            ) Events 
                                                           WHERE Clients.TenantId=@0", DateTime.UtcNow);

private readonly string _orderbyClause = "ORDER BY Clients.Lastname";

// method

public new IEnumerable<Client> AllByTenantAndStatus(Status status)
{
    string sql = String.Format("{0} AND Clients.Status=@1 {1}", _selectClause, _orderbyClause);

    // using external relator
    // return Db.Fetch<Client, Event, Client>(new ClientEventRelator().MapIt,
    //                                               sql, _tenantResolver.CurrentTenantId, status);

    return Db.Fetch<Client, Event>(sql, _tenantResolver.CurrentTenantId, status);
}

Method declarations in Petapoco.cs

public Page<T> Page<T>(long page, long itemsPerPage, string sql, params object[] args) 

and

public void BuildPageQueries<T>(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage) 

both of which accept a single return type parameter.

So I guess my question is that what's the best approach to use the Paged query functionality provided in PetaPoco with MultiPoco queries, as the method provided only works with a single return type?


回答1:


It is complicated, especially because PetaPoco wants to support old DB systems. It means there are used clauses like ROW_NUMBER() OVER... for pagination and when PetaPoco is counting total numbers of records there are often conflicts. Consider:

select * from articles join authors on articles.authorid = authors.id

In case you will have name of the column id on articles and authors table, there is gonna be conflict in automatic generated queries.

SOLUTION

In case you want to work with new version of SQL Server that supports OFFSET / FETCH NEXT you can write simple method for your purpose that will use another methods from PetaPoco. F.e.:

public partial class Database // Create Database class partial and extend it
{
    public Page<TRet> PagedFetch<T1, T2, T3, TRet>(long page, long itemsPerPage, Func<T1, T2, T3, TRet> cb,
        string sql, params object[] args)
    {
        string sqlCount, sqlPage;
        BuildPageQueries<TRet>((page - 1) * itemsPerPage, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);

        sql = string.Format("{0} offset {1} rows fetch next {2} rows only", sql, (page - 1) * itemsPerPage, itemsPerPage);

        var data = Fetch(cb, sql, args);

        var result = new Page<TRet>
        {
            Items = data,
            TotalItems = ExecuteScalar<long>(sqlCount),
            CurrentPage = page,
            ItemsPerPage = itemsPerPage
        };

        result.TotalPages = result.TotalItems/itemsPerPage;

        if ((result.TotalItems % itemsPerPage) != 0)
            result.TotalPages++;

        return result;
    }
}

Finally, dont forget, that you can use OFFSET just when you have sorted data. It means, you should finish your SQL query with "order by something desc" for example.



来源:https://stackoverflow.com/questions/7763632/paged-multi-poco-queries-with-petapoco

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!