How to use a custom DbContext to implement a Repository in Entity Framework?

c# dbcontext entity-framework repository

Question

In our business, we are beginning to create a little framework so that several apps may exchange code. EF4 is what we're utilizing for data access. A custom DbContext class and a generic Repository are available.

public class RMDbContext : DbContext
{
    // ....
}

public interface IRepository 
{
    IQueryable<T> All();
    void Delete(T entity) where T : class;
    void Add(T entity) where T : class;
    void Update(T entity) where T : class;
    int SaveChanges();
    void RollbackChanges();
}

How to implement the repository utilizing our unique DbContext class is the issue at hand (RMDbContext). My colleague believes that letting RMDbContext implement the IRepository interface is the best course of action:

public class RMDbContext : DbContext, IRepository
{
    // ....
}

Since the context is connected to a single contract, I must admit that I don't like this method (IRepository). I think it's preferable to develop a repository implementation that makes advantage of the RMDbContext, like this:

public class Repository<T> : IRepository where T : RMDbContext, new()
{
    protected readonly RMDbContext context;

    public class Repository()
    {
         context = new T();
    }

    // ....
}

What are your thoughts on these 2 strategies? What option would you choose, and why?

1
1
3/1/2013 8:30:47 PM

Accepted Answer

At work, we followed a routine that looked like this:

interface ICRUD<T> : ICreatable<T>, IRetrievable<T>, IUpdatable<T>, IDeletable<T>
{
}

interface ICreatable<T>
{
    T Create();
}

interface IRetrieve<T>
{
    T Retrieve(params object[] keys);
}

interface IUpdatable<T>
{
    void Update(T existing);
}

interface ICreatable<T>
{
    void Delete(T existing);
}

Then we developed a basic repository driven by Entities:

public abstract class BaseRepository<TModel, TEntities> where TEntities : IDbSet<TModel>
{
    protected TEntities Entities {get; set;}
    protected DbContext Db {get; set;}

    public BaseRepository (DbContext db, TEntities entities)
    {
        Db = db;
        Entities = entities;
    }

    public virtual TModel Create() { return Entities.Create (); }
    public virtual TModel Retrieve (params object[] keys) { return Entities.Find (keys); }
    public virtual void Update (TModel existing) { Db.Entry(existing).State = Modified; }
    public virtual void Delete (TModel existing) { Db.Entry(existing).State = Removed; }
}

If you'll see, the BaseRepository just shares method signatures and doesn't really utilize ICRUD. Since we write our code according to interfaces, we can utilize a lot of common code without giving base classes access to capabilities we don't want them to have. Without having any prior knowledge of Entities, a developer is free to implement the data store however they see fit (ICRUD can communicate with a web service, for example), or they are free to extend the functionality offered by the BaseRepository by overriding any of the available methods and performing their own unique actions.

3
11/15/2011 12:54:31 AM

Popular Answer

Personally, I would advise you guys to simply utilize the dbContext, since it already includes all the functions you want.

When developing IRepository, which I did myself, you would have to do some creative programming to find the right ObjectSet or EntitySet to add to or remove from your Add/Delete functions.

As you include inheritance hierarchies into your objectmodel, that code would continue to become more complicated.



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