Reputation: 86
I'm still learning programming and at the moment trying to build a little CRUD app for a friend using ASP.NET MVC5. Since I'm doing it mostly for learning the purpose, I'm trying to understand the Repository pattern. At the moment I have a DBContext class for retrieving data using EF and a Repository class that implements a Interface for all my tables. My main question would be should I have a different Repository class for different tables, since it seems my repository class will grow pretty big if I add more methods to it to manipulate DB data and the Interface kinda seems pointless atm if I'm only using 1 repository class. If I have multiple repository classes should I use Dependency Injection to Inject the needed table to the controller that needs it? And if I do so, then how about Delete action - if I want to delete a Worker that has a List of Bonuses and my controller uses the "Worker Repository" how would I delete the Bonuses related to my Worker? I'm still learning and I am trying to "learn right" so I don't have to re-learn later. So any help would be appreciated.
public class BonusSystemDbContext : DbContext
{
public DbSet<Admin> Admins { get; set; }
public DbSet<Worker> Workers { get; set; }
public DbSet<Position> Positions { get; set; }
public DbSet<Bonus> Bonuses { get; set; }
}
public class BonusSystemRepository : IBonusSystemRepository
{
private BonusSystemDbContext context = new BonusSystemDbContext();
public IEnumerable<Admin> Admins => context.Admins;
public IEnumerable<Bonus> Bonuses => context.Bonuses;
public IEnumerable<Position> Positions => context.Positions;
public IEnumerable<Worker> Workers => context.Workers;
public void SaveBonus(Bonus bonus)
{
if (bonus.ID == 0)
{
context.Bonuses.Add(bonus);
} else
{
Bonus dbEntry = context.Bonuses.Find(bonus.ID);
if (dbEntry != null)
{
dbEntry.WorkerID = bonus.WorkerID;
dbEntry.Date = bonus.Date;
dbEntry.Amount = bonus.Amount;
}
}
context.SaveChanges();
}
public void SavePosition(Position position)
{
if (position.ID == 0)
{
context.Positions.Add(position);
} else
{
Position dbEntry = context.Positions.Find(position.ID);
if (dbEntry != null)
{
dbEntry.Workers = position.Workers;
dbEntry.Name = position.Name;
dbEntry.BeginBonusKg = position.BeginBonusKg;
dbEntry.CentsPerKg = position.CentsPerKg;
}
}
context.SaveChanges();
}
public void SaveWorker(Worker worker)
{
if (worker.ID == 0)
{
context.Workers.Add(worker);
} else
{
Worker dbEntry = context.Workers.Find(worker.ID);
if (dbEntry != null)
{
dbEntry.FirstName = worker.FirstName;
dbEntry.LastName = worker.LastName;
dbEntry.Position = worker.Position;
dbEntry.PositionID = worker.PositionID;
dbEntry.Bonuses = worker.Bonuses;
dbEntry.HealthCertificate = worker.HealthCertificate;
dbEntry.WorkHealthCare = worker.WorkHealthCare;
}
}
context.SaveChanges();
}
}
public interface IBonusSystemRepository
{
IEnumerable<Admin> Admins { get; }
IEnumerable<Bonus> Bonuses { get; }
IEnumerable<Position> Positions { get; }
IEnumerable<Worker> Workers { get; }
void SaveBonus(Bonus bonus);
void SavePosition(Position position);
void SaveWorker(Worker worker);
}
And my db sample Table objects:
public class Worker
{
[Key]
public int ID { get; set; }
[ForeignKey("Position")]
public int PositionID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? WorkHealthCare { get; set; }
public DateTime? HealthCertificate { get; set; }
public virtual Position Position { get; set; }
public virtual ICollection<Bonus> Bonuses { get; set; }
}
public class Bonus
{
[Key]
public int ID { get; set; }
[ForeignKey("Worker")]
public int WorkerID { get; set; }
public DateTime? Date { get; set; }
public decimal Amount { get; set; }
public virtual Worker Worker { get; set; }
}
Upvotes: 6
Views: 803
Reputation: 239290
I'm glad you asked. The easy answer is don't use the repository pattern. The purpose of the repository pattern is to abstract SQL and other low-level data access logic away, and as a result, the pattern is superfluous with ORMs like Entity Framework. In fact, Entity Framework already implements the Unit of Work and Repository patterns: DbContext
is the UoW and each DbSet
is a repository.
That doesn't mean that creating an abstraction over your data layer isn't still a good idea, only that that abstraction shouldn't be a repository. You can use the Service Layer pattern or something like the Command Query Responsibility Segregation (CQRS) pattern.
Note: the Service Layer pattern is very different from Microsoft's "service pattern", which directly relates to using (most often SOAP-based) web services.
Upvotes: 6