问题
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