Entity Framework and Unit of Work

entity-framework unit-of-work

Question

I am utilizing EF/Repository/Unit of Work, however I am finding several elements hard to comprehend. I build a new EF DbContext (EmmaContext) within the UnitOfWork, but when I check inside the repository, I cast it, which I know is incorrect. How can I retrieve the context inside the repository correctly? Perhaps I've taken the wrong turn entirely?

I have my UnitOfWork here:

//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
}

The repository is available at:

//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
}
1
6
8/28/2012 8:20:46 PM

Accepted Answer

Sam: When a concrete repository accepts a concrete unit of work in the ctor, I often feel at ease:

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

Since the repository and UoW often collaborate, they should be familiar with one another.

Naturally, the code that uses these classes is only aware of the interface declarations, not the actual types.

4
8/29/2012 12:50:02 AM

Popular Answer

The My favorite article to date is this.

They handle the repositories in their example in the following manner:

    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;
        }
    }

The context is held by your unit of work, and if it needs to reference a repository, it either creates one if it hasn't already, or passes the context that it is now holding.

Additionally, the post explains how they changed a standard MVC controller implementation to use the unit of work pattern.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow