Entity Framework and Unit of Work

I am using EF/Repository/Unit of Work, but I am having a hard time understanding some details. Inside the UnitOfWork, I create a new EF DbContext (EmmaContext), but look at inside the repository, I cast it which I know is wrong, how do I get the context inside the repo correctly? Maybe I am totally on the wrong path?

Here is my UnitOfWork:

//Interface
public interface IUnitOfWork : IDisposable
{
    void Commit();
}

//Implementation
public class UnitOfWork : IUnitOfWork
{
    #region Fields/Properties
    private bool isDisposed = false;
    public EmmaContext Context { get; set; }
    #endregion

    #region Constructor(s)
    public UnitOfWork()
    {
        this.Context = new EmmaContext();
    }
    #endregion

    #region Methods
    public void Commit()
    {
        this.Context.SaveChanges();
    }

    public void Dispose()
    {
        if (!isDisposed)
            Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        isDisposed = true;
        if (disposing)
        {
            if (this.Context != null)
                this.Context.Dispose();
        }
    }
    #endregion
}

Here is the repository:

//Interface
public interface IRepository<TEntity> where TEntity : class
{
    IQueryable<TEntity> Query();
    void Add(TEntity entity);
    void Attach(TEntity entity);
    void Delete(TEntity entity);
    void Save(TEntity entity);
}

//Implementation
public abstract class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
    #region Fields/Properties
    protected EmmaContext context;
    protected DbSet<TEntity> dbSet;
    #endregion

    #region Constructor(s)
    public RepositoryBase(IUnitOfWork unitOfWork)
    {
        this.context = ((UnitOfWork)unitOfWork).Context;
        this.dbSet = context.Set<TEntity>();
    }
    #endregion

    #region Methods
    public void Add(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public void Attach(TEntity entity)
    {
        dbSet.Attach(entity);
    }

    public void Delete(TEntity entity)
    {
        dbSet.Remove(entity);
    }

    public IQueryable<TEntity> Query()
    {
        return dbSet.AsQueryable();
    }

    public void Save(TEntity entity)
    {
        Attach(entity);
        context.MarkModified(entity);
    }
    #endregion
}

Answers


Sam: I usually feel comfortable with a concrete Repository taking a concrete UnitOfWork in the ctor:

   public RepositoryBase(UnitOfWork unitOfWork)
   {
        this.context = unitOfWork.Context;
        this.dbSet = context.Set<TEntity>();
   }

The repository and UoW typically work in concert and need to know a little bit about each other.

Of course the code consuming these classes only know about the interface definitions and not the concrete types.


This is the best article I've read.

In their example, they manage the repositories like this:

    private SchoolContext context = new SchoolContext();
    private GenericRepository<Department> departmentRepository;
    private GenericRepository<Course> courseRepository;

    public GenericRepository<Department> DepartmentRepository
    {
        get
        {

            if (this.departmentRepository == null)
            {
                this.departmentRepository = new GenericRepository<Department>(context);
            }
            return departmentRepository;
        }
    }

Your unit of work holds the context, and if it needs to reference a repository, it creates it if it has not been created, and passes in the context that it's holding.

The article also walks through how they converted a regular MVC controller implementation into using the unit of work pattern.


In this post says that you have to implement IUnitOfWork interface in your repository base.

I hope this helps. Regards


Unit of Work Repository

UnitOfWork is for managing atomic operations.

Repository encapsulates the set of objects persisted in a data store and the operations performed over them.

If you pass the context or UnitOfWork, than you do not implement UnitOfWork+Repository pattern, cause you pulling out from UnitOfWork its responsibility. Aka you do not need it .

Right implementation if you only pass DbSet. Actually you do not need more.


Need Your Help

Saving View bitmap with getDrawingCache gives a black image

android image caching view

Everything I tried with setDrawingCacheEnabled and getDrawingCache was not working. The system was making an image but it just looked black.

How do for loops work in C?

for-loop computer-science

In the following for loop, how does the flow of control work?