views:

46

answers:

3

We've got the following repository method

public IList<Foo> GetItems(int fooId, int pageIndex, int pageSize
, string sortField, string sortDir, out int totalItems)
{
// Some code
}

My question is: is it ok to use out in this way. I'm somewhat uncomfortable with out, but can't come up with a better way to write this as a single call.

A: 

I don't see why you want to do it in one call. If you need to optimize the repository roundtrip for a separate total count call, I believe you are prematurely micro-optimizing unless you've measures that this particular call is your perf problem. And if you've measured it and it is, I reckon you have bigger problems with your repository.

I personally would stick with a simple Count property on the same object that exposes GetItems above.

Update: To address your question are there reasons not to design it as a single call:

It makes your API more complex and more ambiguous than it needs to be. GetItems() main intention (as declared above) is to deal with a single page of items; adding the out parameter for the total count of items overloads that semantic.

Here's something to consider - if I care only about the total count of items, will I have to call GetItems or will there be a separate method? If there is a separate method, why are there two ways of accessing the same information and is it possible that they might return different results? And if there is no separate result, why should I have to get a full page of records just to get the total count of items in the repository?

Franci Penov
Is there a good reason not to do it as a single call?
John
disagree, I'm all for avoiding premature optimization, but unnecessary round-trips almost always impact performance relatively early.
eglasius
@Freddy Rios - without knowledge how the repository is implemented, you can't claim that having a separate `Count` property on the same object that exposes `GetItems` will result in a round trip.
Franci Penov
I agree that the repository should contain a separate Count() method. You shouldn't have to get the items to determine the count if you don't need them.
John
+1  A: 

What about this?

public class ItemsList
{
    public IList<Foo> Items { get; set; }
    public int TotalCount { get; set; }
}

public ItemsList GetItems(int fooId, int pageIndex, int pageSize, string sortField, string sortDir)
{
    return new ItemsList { Items = ..., TotalCount = ... };
}

You can store additional information as well.

public class ItemsList
{
    public IList<Foo> Items { get; set; }
    public int TotalCount { get; set; }
    public string SortField { get; set; }
    public string SortDirection { get; set; }
    public int PageIndex { get; set; }
    public int PageSize { get; set; }
}

Or even create a generic class.

mak
Are there any issues with creating a generic class?
John
+1  A: 

I found the answer that I was looking for, though not from the comments. Thank you, though for your help.

It turns out that MVC guru Rob Conery posted some time ago about using a PagedList. It's elegant pattern and according to the blog, ScottGu has used it in demos. Basically, instead of using IList<T> and List<T>, you use IPagedList<T> and PagedList<T>. PagedList<T>: List<T>, IPagedList<T>.

public interface IPagedList
{
    int TotalCount { get; set; }
    int PageIndex  { get; set; }
    int PageSize { get; set; }
    bool IsPreviousPage { get; }
    bool IsNextPage { get; }   
}

There's more code to it, so check out Rob's blog.

http://blog.wekeroad.com/blog/aspnet-mvc-pagedlistt/

John
On thing that I really like about this is that it contains more than just the count and it would be easy to add my own other properties and methods as well, which could help keep the client code cleaner. So the list object itself contains which fields were sorted on and direction. One could add a property string[] TopPageIndeces, which could be useful for creating paged hyperlinks.
John