views:

33

answers:

2

Hi all. I'm new to mvc and this whole way of programming is pretty unfamiliar for me, so be gentle ...

I have in my article repository:

public IQueryable<Article> GetArticles(int? category, int? position)
{
    return from a in dc.Articles
           where a.LanguageIndex == lang && a.CategoryIndex == category && a.ArticlePosition == position
           select a;
}

How can I pass the parameters category and position from the interface while maitaining separation of concerns ?

I thought about :

public interface IArticleRepository
{
    IQueryable<Article> GetArticles(Article a);
}

and passing the parameters along with the Article object, but this means I would have to pass the category and position in the controller. Am I in the right direction here ???

+1  A: 

Not sure how this relates to separation of concerns. I can see where it might seem the abstraction is leaky; is it your concern that it seems users must know a little too much about how the repository holds your Articles?

Until someone comes up with a performant method of separating implementation from models, storage abstractions will always be leaky. You can beat yourself up over it or just do your best and deal.

Your second method is, IMHO, worse than the first. You still have to stipulate the category and position in your Article, so you still have the leak in addition to a weird API that confuses parameters with entities.

I'd definitely go with the first version over the second. If I were to do anything, I would refactor to make CategoryIndex and ArticlePosition entities (Category and Position tables linked to the Article table). You could then refactor your API to the more appealing:

var cat = CategoryRepository.GetCategory("foo");
var pos = PositionRepository.GetPosition("bar");
var article = ArticleRepository.GetArticle(cat, pos);

Is this any better than what you already have? Probably not.

Will
A: 

Fist I would separate out the basic query:

public IQueryable<Article> GetArticles()
{
    return from a in dc.Articles select a;
}

public IQueryable<Article> GetArticles(int? category, int? position)
{
    return GetArticles ().Where (a => a.LanguageIndex == category && a.CategoryIndex == position).AsQueryable ();
}

Now if you want to move the specific query filter out of your repository you can move it to an extension method:

public static IQueryable<Article> WithCategory(this IQueryable<Article> articles, int? category, int? position)
{
    return articles.Where (a => a.LanguageIndex == category && a.CategoryIndex == position).AsQueryable ();
}
Todd Smith