3

PetaPoco 很棒,涵盖了分页查询Multi-Poco 映射,但我想弄清楚是否有办法将它们一起做?

编辑:

这是我用来获取 MultiPoco 数据的存储库方法:

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

Petapoco.cs 中的方法声明

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

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

两者都接受一个返回类型参数。

所以我想我的问题是,将 PetaPoco 中提供的分页查询功能与 MultiPoco 查询一起使用的最佳方法是什么,因为提供的方法仅适用于单一返回类型?

4

1 回答 1

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.

于 2014-09-17T19:02:12.740 回答