In the first part of this series we didn’t really look at the MVC framework. We talked about what it is and what it does but didn’t look at any code. We did however plan out what we wanted our application to do and created our database schema that will support our application. In this part we are going to jump in and get an MVC Application created and look at the Model portion of the application. We’ll create our domain objects and data repositories. It is important to note that I will be using the Repository Pattern with Pipes and Filters Pattern. So we’ll have our data repositories and their relevant filters. We will then create data service objects that encapsulate the repositories. Also, I will be using LINQ To SQL to interact with the database. If you prefer a different method of data access feel free to use something else. Finally, before we get started, I will not be writing unit tests for this series, at least not showing them in the posts, in order to keep things simple and to keep the posts from getting too long.

 

Creating The Application

I’ll assume you have already created the database schema that we talked about in the part 1. It is important to have the Data Connections setup in the Server Explorer as this will be required to create the LINQ to SQL classes. So, in Visual Studio create a new project and use the settings like the screenshot below.

When you click OK, VS will create a new MVC application for you. It will contain a couple Controllers and Views that make up the MVC demo application. We’ll ignore this for now. To keep things simple I will be using the layout of the demo app but I will be deleting some files later on.

 

The LINQ To SQL Diagram

In the Server Explorer you should have your Data Connection setup to your database with our application tables. Creating the data diagram is super easy. All you do is drag each table from the Server Explorer to the design surface and VS will create the diagram and relationships for you. Also, after you compile your application you will have model objects that reflect your database tables and their relationships.

ASP.NET MVC

The Repository Pattern

As I said earlier I am using the repository pattern to handle my data access. For each model I will create an interface and repository class for interacting with that model. Below is the interface and class for the Tasks model repository. internal interface

   1: ITasksRepository 
   2: { 
   3:     IQueryable<Task> GetTasks(); 
   4: } 
   5:  
   6: public class TasksRepository : ITasksRepository 
   7: { 
   8:     private TaskListDataContext db; 
   9:  
  10:     public TasksRepository() 
  11:     { 
  12:         db = new TaskListDataContext(); 
  13:     } 
  14:  
  15:     public IQueryable<Task> GetTasks() 
  16:     { 
  17:         var tasks = from t in db.Tasks select t; 
  18:         return tasks; 
  19:     } 
  20: }

This simple repository has a method that fetches all the Task objects from the database through LINQ To SQL. Notice the .ToList() on the methods return statement. This turns the dynamic object tasks into a List<Task> to be returned.

Filtering The Repository

Now that we have a method to return the Task objects in our database, we need a way to filter those results to get what we want. I am going to be using extension methods to apply the filters. This keeps things neat and clean.

Because our repository returns IQueryable we can apply a filter and use LINQ to filter the existing results. Notice that the filter also returns IQueryable. This allows you chain filters making advanced queries a breeze.

 

Building Our Data Service

Now that we have a repository and filters in place we can construct our data service that our application will use. It may seem like extra work to wrap the repository in a service but it allows you to make changes to the repository and filters without having to touch any application code. This is a huge benefit from just a small amount of extra work.

   1: public interface ITasksService 
   2: { 
   3:     IList<Task> GetTasks(); 
   4:     Task GetTaskById(int id); 
   5: } 
   6:  
   7: public class TasksService : ITasksService 
   8: { 
   9:     ITasksRepository repository; 
  10:  
  11:     public TasksService() : this(new TasksRepository()) { } 
  12:  
  13:     public TasksService(ITasksRepository repository) 
  14:     { 
  15:         this.repository = repository; 
  16:     } 
  17:     
  18:     public IList<Task> GetTasks() 
  19:     { 
  20:         return repository.GetTasks().ToList(); 
  21:     } 
  22:     
  23:     public Task GetTaskById(int id) 
  24:     { 
  25:         return repository.GetTasks().WithId(id).Single(); 
  26:     } 
  27: } 

Now here is how we would use the service in our application.

   1: ITaskService service = new TaskService(); 
   2: IList<Task> tasks = service.GetTasks(); 
   3: Tasks task = service.GetTaskById(1);

Pretty simple, huh?

 

The Generated Classes

The classes that LINQ creates from our data diagram go beyond just an identical representation of our database tables. LINQ takes the relationships into accounts. For example, we used our Tasks table in the code above to create a TasksRepository. This Id column of this table is a foreign key in the TodoItems table which links individual to do items to a specific task. The IQueryable<Task> that is returned from the GetTasks method is a collection of Task objects. So in the generated Task model objects that instances of the model will have an EntitySet<TodoItem> collection as part of the instance. LINQ really is powerful in this way. It gives us huge power while simplifying our code. Also, if you change the Delay Loaded property of the TaskId foreign key in the TodoItems table you have instant Lazy Loading with no work at all. Makes you wonder why you ever tried to write that functionality yourself doesn’t it?

 

Wrap Up

So we have setup our application, configured LINQ To SQL to generate our Model classes, and we have look at how to implement a Repository Pattern for data access with filters. That is a lot to take in but I hope you see the potential and power of where we are going with ASP.Net MVC and will continue to read this series. Again we didn’t really look at ASP.Net MVC. Don’t be angry. We were laying the foundation first. I promise there will be some juicy MVC bits in the next article. I plan to look at routing and controllers in the next post and if I don’t get too long winded with those we may take a peek at views. To make sure you don’t miss a beat grab the Dev102 RSS feed. You may also be interested to follow what I have to say on my web development blog or grab my RSS feed. Enjoy!

Tags :

14 Responses to “Working With ASP.Net MVC Part 2 – The Model And The Repository Pattern”


  1. Derik Whittaker

    Said on December 11, 2008 :

    You name the post Asp.Net then never talk about MVC, then at the end you say ‘Again we didn’t really look at ASP.Net MVC. Don’t be angry.’. Name the post so it conveys the actual content of the post. Putting a fake name on the post to get hits is sad, just sad.

  2. Daniel

    Said on December 12, 2008 :

    I’m trying to get my head around this pattern, but one thing keeps tripping me up: If you use LINQ-to-SQL classes as the model in your interface, then you can’t write other repositories using other data stores. For example, you can’t now write an EntityFrameworkRepository, a Sql Data Services, Azure Table repository, or even an in-memory repository. In each case, either a) you can’t use the same classes, or b) the queries must look different. Since there can only be one implementation of ITaskRepository, it calls to question the usefulness of the pattern. In an ideal world, your repository would work against POCOs, but in practice this is hard to implement.

  3. WebDevVote

    Said on December 13, 2008 :

  4. Justin

    Said on December 13, 2008 :

    Using LINQ was a choice I made knowing that it limits you to SQL Server…you are free to use something different if you need to be concerned about switching data sources.

    The way I have set it up you can completely change the repository code, make some minor changes to the services (mostly types) and not have to touch your business logic.

    If you need to protect against future changes you could define your own model classes (different from LINQ generated classes) and have the LINQ queries populate your custom classes to be uses in the services and business logic.

  5. Lerxst

    Said on December 14, 2008 :

    I want my 5 minutes back.

  6. shilpi

    Said on January 23, 2009 :

    very nice and simple explanation

  7. Dominic Pettifer

    Said on March 24, 2009 :

    I think what ‘Daniel’ is trying to say is what is the point of using the Repository Pattern if you’re just going to return strongly typed LING 2 SQL objects? I thought the whole point of the Repository pattern was that you could rip out one Repository (LINQ 2 SQL say) and replace it with a completely different one (Entity Framework, NHibernate etc.), all without changing the code that calls your IRepository interfaces.

    With your implementation, because you’re returning the LINQ 2 SQL objects, the code using your IRepository interfaces would need to change if you switched to another data access layer, which defeats the purpose of using Interfaces does it not?

  8. behnam

    Said on May 11, 2009 :

    nice articel but can anyone explain diffrent between repository pattern and n tier?
    thanks

  9. Mark D

    Said on May 11, 2009 :

    You need to use Mappers in the repo to map the LINQ classes to POCOs and return those to the service.

  10. strike

    Said on December 22, 2009 :

    Is it just me, or ain’t that post missing a code-snipplet under the headline “Filtering The Repository” ???
    Would be nice to see how you suppose to write the “WithId(…)” method…

  11. hotosmeapsisp

    Said on April 19, 2010 :

  12. bhupendra

    Said on December 8, 2011 :

    WithId is not wroking

  13. Bala

    Said on October 25, 2012 :

    Hi,

    I am implementing Repository Pattern in one of my project based on ASP.NET MVC4 and N-Tier Architecture. I am little confused as how to implement Custom Membership with Repository Pattern. Here are how I have implemented my classes so far.

    Generic Repository

    public interface IRepository where T : class
    {
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    IQueryable GetAll();
    T FindBy(Expression<Func> expression);
    IQueryable FilterBy(Expression<Func> expression);
    }

    Repository Base Class

    public abstract class Repository : IRepository where T : class
    {
    private STNDataContext _stnDataContext;
    private readonly IDbSet _dbSet;

    protected Repository(IDatabaseFactory databaseFactory)
    {
    DatabaseFactory = databaseFactory;
    _dbSet = StnDataContext.Set();
    }

    protected IDatabaseFactory DatabaseFactory { get; private set; }
    public STNDataContext StnDataContext
    {
    get { return _stnDataContext ?? (_stnDataContext = new STNDataContext()); }
    }
    public void Add(T entity)
    {
    _dbSet.Add(entity);
    _stnDataContext.Commit();
    }

    public void Delete(T entity)
    {
    _dbSet.Remove(entity);
    }

    public void Update(T entity)
    {
    _dbSet.Attach(entity);
    _stnDataContext.Entry(entity).State = EntityState.Modified;
    _stnDataContext.Commit();
    }

    public IQueryable GetAll()
    {
    return _dbSet.ToList().AsQueryable();
    }

    public T FindBy(Expression<Func> expression)
    {
    return FilterBy(expression).SingleOrDefault();
    }

    public IQueryable FilterBy(Expression<Func> expression)
    {
    return GetAll().Where(expression).AsQueryable();
    }

    User Repository Interface

    public interface IUserRepository : IRepository
    {
    }

    User Repository

    public class UserRepository : Repository, IUserRepository
    {
    public UserRepository(IDatabaseFactory databaseFactory)
    : base(databaseFactory)
    {
    }
    }

    Heres my Business Logic Layer

    Generic Service Interface

    public interface IService
    {
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    IEnumerable GetAll();
    T FindBy(Expression<Func> expression);
    IEnumerable FilterBy(Expression<Func> expression);
    }

    Service Base

    public class Service : IService where T : class
    {
    public void Add(T entity)
    {
    throw new NotImplementedException();
    }

    public void Delete(T entity)
    {
    throw new NotImplementedException();
    }

    public void Update(T entity)
    {
    throw new NotImplementedException();
    }

    public IEnumerable GetAll()
    {
    throw new NotImplementedException();
    }

    public T FindBy(Expression<Func> expression)
    {
    throw new NotImplementedException();
    }

    public IEnumerable FilterBy(Expression<Func> expression)
    {
    throw new NotImplementedException();
    }
    }

    User Service Interface

    public interface IUserService : IService
    {
    }

    User Service Implementation

    public class UserService : Service, IUserService
    {
    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;

    public UserService(IUserRepository userRepository, IRoleRepository roleRepository)
    {
    _userRepository = userRepository;
    _roleRepository = roleRepository;
    }

    public IList GetAllUsers()
    {
    return _userRepository.GetAll().ToList();
    }

    public User GetUser(int id)
    {
    return _userRepository.FindBy(x => x.UserId == id);
    }

    public User GetUser(string userName)
    {
    return _userRepository.FindBy(x => x.Username.Equals(userName));
    }

    public void CreatUser(User user)
    {
    _userRepository.Add(user);
    }

    public IList GetUsersForRole(string roleName)
    {
    return _userRepository.FilterBy(x => x.Role.RoleName.Equals(roleName)).ToList();
    }

    public IList GetUsersForRole(int roleId)
    {
    return _userRepository.FilterBy(x => x.Role.RoleId == roleId).ToList();
    }

    public IList GetUsersForRole(Role role)
    {
    return GetUsersForRole(role.RoleId);
    }

    }
    Hi Bob,
    I am developing one application using ASP.NET MVC4, N-Tier Architecture and Repository Pattern. I want to implement Custom Membership functionality and refering your gpsnerd application as reference. I am little confused implementing the same. Can you help?

    I am not very sure on Am I going the right way? If yes how do i implement my UserService class. ???

    If no, what changes do i need to implement.

    Any help on this is highly appreciable. Thanks in advance

  14. Bala

    Said on October 25, 2012 :

    Hi,

    I am implementing Repository Pattern in one of my project based on ASP.NET MVC4 and N-Tier Architecture. I am little confused as how to implement Custom Membership with Repository Pattern. Here are how I have implemented my classes so far.

    Generic Repository

    public interface IRepository where T : class
    {
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    IQueryable GetAll();
    T FindBy(Expression<Func> expression);
    IQueryable FilterBy(Expression<Func> expression);
    }

    Repository Base Class

    public abstract class Repository : IRepository where T : class
    {
    private STNDataContext _stnDataContext;
    private readonly IDbSet _dbSet;

    protected Repository(IDatabaseFactory databaseFactory)
    {
    DatabaseFactory = databaseFactory;
    _dbSet = StnDataContext.Set();
    }

    protected IDatabaseFactory DatabaseFactory { get; private set; }
    public STNDataContext StnDataContext
    {
    get { return _stnDataContext ?? (_stnDataContext = new STNDataContext()); }
    }
    public void Add(T entity)
    {
    _dbSet.Add(entity);
    _stnDataContext.Commit();
    }

    public void Delete(T entity)
    {
    _dbSet.Remove(entity);
    }

    public void Update(T entity)
    {
    _dbSet.Attach(entity);
    _stnDataContext.Entry(entity).State = EntityState.Modified;
    _stnDataContext.Commit();
    }

    public IQueryable GetAll()
    {
    return _dbSet.ToList().AsQueryable();
    }

    public T FindBy(Expression<Func> expression)
    {
    return FilterBy(expression).SingleOrDefault();
    }

    public IQueryable FilterBy(Expression<Func> expression)
    {
    return GetAll().Where(expression).AsQueryable();
    }

    User Repository Interface

    public interface IUserRepository : IRepository
    {
    }

    User Repository

    public class UserRepository : Repository, IUserRepository
    {
    public UserRepository(IDatabaseFactory databaseFactory)
    : base(databaseFactory)
    {
    }
    }

    Heres my Business Logic Layer

    Generic Service Interface

    public interface IService
    {
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    IEnumerable GetAll();
    T FindBy(Expression<Func> expression);
    IEnumerable FilterBy(Expression<Func> expression);
    }

    Service Base

    public class Service : IService where T : class
    {
    public void Add(T entity)
    {
    throw new NotImplementedException();
    }

    public void Delete(T entity)
    {
    throw new NotImplementedException();
    }

    public void Update(T entity)
    {
    throw new NotImplementedException();
    }

    public IEnumerable GetAll()
    {
    throw new NotImplementedException();
    }

    public T FindBy(Expression<Func> expression)
    {
    throw new NotImplementedException();
    }

    public IEnumerable FilterBy(Expression<Func> expression)
    {
    throw new NotImplementedException();
    }
    }

    User Service Interface

    public interface IUserService : IService
    {
    }

    User Service Implementation

    public class UserService : Service, IUserService
    {
    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;

    public UserService(IUserRepository userRepository, IRoleRepository roleRepository)
    {
    _userRepository = userRepository;
    _roleRepository = roleRepository;
    }

    public IList GetAllUsers()
    {
    return _userRepository.GetAll().ToList();
    }

    public User GetUser(int id)
    {
    return _userRepository.FindBy(x => x.UserId == id);
    }

    public User GetUser(string userName)
    {
    return _userRepository.FindBy(x => x.Username.Equals(userName));
    }

    public void CreatUser(User user)
    {
    _userRepository.Add(user);
    }

    public IList GetUsersForRole(string roleName)
    {
    return _userRepository.FilterBy(x => x.Role.RoleName.Equals(roleName)).ToList();
    }

    public IList GetUsersForRole(int roleId)
    {
    return _userRepository.FilterBy(x => x.Role.RoleId == roleId).ToList();
    }

    public IList GetUsersForRole(Role role)
    {
    return GetUsersForRole(role.RoleId);
    }

    }

    I am not very sure on Am I going the right way? If yes how do i implement my UserService class. ???

    If no, what changes do i need to implement.

    Any help on this is highly appreciable. Thanks in advance

Post a Comment