Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository Pattern C#

Tags:

c#

asp.net-mvc

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; }
}
like image 208
Stenehr Avatar asked May 01 '17 18:05

Stenehr


People also ask

What is the repository pattern?

The Repository pattern. Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

What is C# repository pattern?

The Repository Design Pattern in C# Mediates between the domain and the data mapping layers using a collection-like interface for accessing the domain objects. In other words, we can say that a Repository Design Pattern acts as a middle layer between the rest of the application and the data access logic.

Why we use repository pattern in MVC?

Why the repository pattern is used? The main purpose of the repository pattern is to isolate the data access layer and business logic.In Asp.Net MVC model is used to interact with the Data Access layer and Controller for performing Data access operation. The controller is responsible for passing data to the view.

What is generic repository pattern C#?

The generic repository pattern implements in a separate class library project. It uses the "Code First" development approach and creates a database from a model, using migration. This article demonstrates a sample Application, which has one too many relationships in ASP.NET Core with Entity Framework Core.


1 Answers

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.

like image 102
Chris Pratt Avatar answered Oct 17 '22 09:10

Chris Pratt