1

Good day,

I'm using repository pattern. But someone advised me to use include Unit of Work. I read a lot of articles and honestly I found a docs that are too complicated to understand.

Supposing I have a non-generic repository.

// My Interface 
public interface IProductRepository{
    IQueryable Products();
    IQueryable ProductById(int id);
    void InsertProduct(Product product);
    void UpdateProduct(Product product);
    void DeleteProductById(int id);
}

// Abstract Implementation

public class ProductRepository : IProductRepository{
    private readonly MyDbContext context;

    public ProductRepository(MyDbContext context){
        this.context= context;
    }

    public IQueryable Products(){  
        context.Product(); 
    }
    public IQueryable ProductById(int id){ 
        context.Product().Where(prod=>prod.Id == id);    
    }
    public void InsertProduct(Product product){
        context.Product.Add(product);
        context.SaveChanges();
    }
    public void UpdateProduct(Product product){
        context.Product.Update(product);
        context.SaveChanges();
    }
    public void DeleteProductById(int id){
        var product = ProductById(id);
        context.Product.Remove(product);
        context.SaveChanges();
    }
}

My question is, how can I use Unit of Work here? Can you please show me a code below. It will be so much helpful for me to understand.

10
  • 2
    Your underlying ORM (Entity Framework) already follows both repository and unit of work patterns. So just throwing away your abstration over another (identical) abstration will reach the goal. But if you insist - just duplicate its functionality. Remove all context.SaveChanges from UpdateProduct, DeleteProduct etc, and add separate SaveChanges method (which will of course do nothing more than cotnext.SaveChanges). Commented Mar 13, 2018 at 5:30
  • You mean, I don't need to learn unit of work when using EF? Is that what you mean? Because EF has it's own Repository and unit of work patterns? Commented Mar 13, 2018 at 5:50
  • If you don't know what unit of work is - then sure you need to learn what is it, how are you going to implement it otherwise. And then you will see that EF DbContext already follows unit of work pattern. Commented Mar 13, 2018 at 6:02
  • Good Cross ref: stackoverflow.com/questions/10776121/… Commented Mar 13, 2018 at 6:08
  • @Evk if EF has it, so I don't need to implement Unit of Work pattern right? Commented Mar 13, 2018 at 6:13

3 Answers 3

2

In your IProductRepository add a Save method

// My Interface 
public interface IProductRepository{
    // ...
    void Save();
}

Then in concrete ProductRepository, you do two things:

  1. Remove all calls to context.SaveChanges();
  2. In IProductRepository.Save implementation, call context.SaveChanges()

Do all operations on the dbcontext, and in the end call Save().

static void main() {
    // ...
    this.productRepository.InsertProduct(product1);
    this.productRepository.InsertProduct(product2);
    this.productRepository.InsertProduct(product3);
    this.productRepository.Save();
}

That's the gist of unit of work.

Sign up to request clarification or add additional context in comments.

Comments

1

The main reason why you need unit of work in your project is you need to make sure all your repository have same context. The relationship between unit of work and repository like the relationship between DbContext and DbSet in Entity framework.

If you want to implement your UnitOfWork you can ref this link: https://codereview.stackexchange.com/questions/47879/unit-of-work-and-repository-with-entity-framework-6

Comments

0

This is really more of an answer to your questions in the comments about EF doing the work
If you look at how EFCore does this, you actually define a context and define what classes you want inside that context. From https://learn.microsoft.com/en-us/ef/core/ they define a BloggingContext that inherits from DbContext. The example below is from microsoft:

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=localdb)\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;");
    }
}

They have a Blog class and a Post class in this example that get created into tables when a migration and update are ran on the database(https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/). Now that you have Blog and Post defined inside the BloggingContext you can create an instance(good to use dependency injection you can read more about that here if you like https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext) of the BloggingContext and use linq to your hearts content, no need for a custom repository or unit of work. EF does the work once you have defined what classes you want in what context. With that said, we do use repository and unit of work where I work, if there is a reason to use the patterns great, but past that or learning it for yourself, EF does really well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.