Reputation: 2184
I have created a very basic repository pattern and I'd like include a clean way to load related data. I have seen people use .Include() previously but I'm not 100% certain how I would introduce this to my solution.
Here is my repository so far:
/Repository/IRepository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyProject.Repository
{
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
T GetById(object Id);
void Insert(T obj);
void Update(T obj);
void Delete(Object Id);
void Save();
}
}
/Repository/Repository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SeaBay.Models;
using System.Data.Entity;
namespace MyProject.Repository
{
public class Repository<T> : IRepository<T> where T : class
{
private myEntities db;
private DbSet<T> dbSet;
public Repository()
{
db = new myEntities();
dbSet = db.Set<T>();
}
public IEnumerable<T> GetAll()
{
return dbSet;
}
public T GetById(object Id)
{
return dbSet.Find(Id);
}
//... etc etc
}
Basic Controller
public class MyController : Controller
{
private IRepository<entity> _repository = null;
public MyController()
{
this._repository = new Repository<entity>();
}
public ActionResult Index()
{
var mydata = _repository.GetAll();
return View(mydata);
}
public ActionResult Details(int Id)
{
var mydata = _repository.GetById(Id);
return View(mydata);
}
}
Lets say for exmaple that I have two tables of data 'Student' and 'Classes', how would I return this related data in a repository pattern assuming the IRepository was using 'Student' as it's source?
Upvotes: 2
Views: 1083
Reputation: 2792
The most likely reason that folks aren't jumping on answering this is that generic repositories tend to make for either very leaky abstractions, or very poorly performing applications (are you going to call GetAll() and return 10,000 entities when only 25 are displayed on a page at a time?). Abstracting away data access logic from the business and UI layers is great, but trying to create a one-size-fits-all approach generally leads to something that is either overly simplistic or far too complex.
Try adding an additional layer of abstraction on top of your generic repository so that each entity type has a corresponding repository contract (interface). Then create a concrete repository class that implements your contract. The concrete class is where you would determine what data to include and when, and the contract could be used to have entity specific methods, overloads, etc. that account for the complexity of the entity hierarchy. Your business and UI layers would (either directly or via dependency injection) interact with the concrete implementation instead of having the concrete implementation inside of your business and UI layers.
Upvotes: 2