1

What is the right way to use repository pattern (with entity framework) when working with multiple set of entities?

Should I create a repository for every entity?
e.g.:
Having following entities: Articles, categories and comments.
Should i have a repository for each one?

I was using repository like this:

public class BaseArticleRepository : BaseRepository
{

   private ContentModel _contentctx;
   public ContentModel Contentctx
   {
        get
        {
            if ((_contentctx == null))
            {                   
                _contentctx = new ContentModel();
            }

            return _contentctx;
        }
        set { _contentctx = value; }
   }
  // IDisposable Support code comes here....                        
  }

And sample repository for Articles:

public class ArticlesRepository : BaseArticleRepository
{
   public Article GetArticleById(int id)
   {

       var article = Contentctx.Articles.Where(o => o.ArticleID == id).FirstOrDefault();          
       return article;
   }

   public List<Article> GetArticles()
   {

       var articles = Contentctx.Articles.ToList();         
       return articles;
   }

   public List<ArticleHeader> GetArticlesHeaders()
   {
       var articles = (from article in Contentctx.Articles
                      select new ArticleHeader
                      {
                          ArticleID = article.ArticleID,
                          Title = article.Title,
                          CategoryTitle = article.Articles_Categories.Title,                            
                          AddedBy = article.AddedBy,
                          AddedDate = article.AddedDate,
                          ViewCount = article.ViewCount

                     }).ToList();


      return articles;
   }
   public List<ArticleHeader> GetArticlesHeaders(int PageIndex, int PageSize)
   {


         var articles = (from article in Contentctx.Articles
                         select new ArticleHeader
                         {
                                ArticleID = article.ArticleID,
                                Title = article.Title,
                                CategoryTitle = article.Articles_Categories.Title,
                                AddedBy = article.AddedBy,
                                AddedDate = article.AddedDate,
                                ViewCount = article.ViewCount

                         }).OrderBy(p => p.AddedDate).Skip(PageSize * PageIndex).Take(PageSize).ToList();

            return articles;
 }



   public int GetArticleCount(string txtFilter)
   {

      int ret = Contentctx.Articles.Where(o => o.Title.Contains(txtFilter)).Count();    
      return ret;

   }



  public int AddArticle(Article article, int categoryId)
  {

          Contentctx.AddToArticles(article);              
  }
}

Basically every repository implements all CRUD data (including getting data with filters and sorts), though I read in some blogs that this is wrong repository pattern implementation because Repository must implement only basic,generic, function to retrieve and insert (remove modify) data.
All sorting, filtering must be done locally in memory.

But I preform to what ever i can on server side (sqlserver).
Why should I load all articles (with all fields) from database if I need only title and abstract?

leaver
  • 11
  • 2
  • 1
    "All sorting, filtering must be done locally in memory." - Where did you read this? Not sure what back-end you are using, but surely a sql query can sort/filter data much more efficiently than you do it in memory (given that you spend equal amount of effort programming each). What if you have a million rows of data to filter through? – Andrew Savinykh Sep 15 '11 at 12:54

2 Answers2

2

I would suggest creating a repository for each aggregate root you are dealing with. An aggregate root being the data structure that you actually want to have as the object you are manipulating, i.e. Customer, it may have Address, Orders, Invoices, etc as substructures (the actual customer you retrieve with those related substructures an aggregate of the various tables).

Community
  • 1
  • 1
Lazarus
  • 41,906
  • 4
  • 43
  • 54
  • Yes aggregate will work for me. But what about the repository implementation, is it ok to have specific queries like those in my post? or the implementation must be generic like here: http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx – leaver Sep 15 '11 at 13:22
  • Strictly speaking the repository pattern should be fairly dumb and the logic sits in a layer above that but I would always include methods such as "GetByID" in the repository. You are only trying to abstract the data access layer in the repository, nothing more. Think about where you want to use that information. The repository will present data to the business logic layer, the BLL presents data to the presentation layer... that will often answer questions as to where you should implement a particular method. – Lazarus Sep 15 '11 at 14:05
  • this is a nice approach http://blog.lowendahl.net/?p=249 but it will require me to implement "ICriteria" for every query that I need (and I a lot) – leaver Sep 15 '11 at 19:49
0

To say "This is the right way" is always a risky affirmation, but I think you should create aggregates (Entities that are composed by various tables) and once it have been done, try to learn about the Unit Of Work (UoW) pattern. The UoW is the way that I use to deal with multiple repositories.

BTW, I'm agree with zespri. Sort and filter in memory is not a good idea.

Jonathan
  • 11,809
  • 5
  • 57
  • 91