K-Dawg
K-Dawg

Reputation: 3299

Entity Framework Generics

Background:

Whilst writing my own MVC application I had a requirement to interact with a database. I decided to use generics with entity framework Repositories like so:

    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    DatabaseContext<TEntity> _dbContext;
    Database _database;

    public IQueryable<TEntity> All
    {
        get
        {
            return (IQueryable<TEntity>) _dbContext.Items;
        }
    }

    public Repository()
    {
        _dbContext = new DatabaseContext<TEntity>();
        _database = _dbContext.Database;
    }
}

As you can see I also use a generic DbContext.

My Two Part Question

I took a while to sit back and look at the solution before proceeding with it. I realise that this forces me to create multiple DB context objects.

i) Is this bad practice?

ii) Will it have a noticeable impact on the efficiency of my solution?

Upvotes: 0

Views: 80

Answers (2)

Mithun Pattankar
Mithun Pattankar

Reputation: 1372

Multiple db context(leads to creating multiple database) are created because every generic context is treated as new database connection.

We have multiple dbContext which can target one database. It can be achieved as below

  1. Create DbContext(generic one in your case)

    public class HumanResourceContext : BaseContext<HumanResourceContext>
    {
        //DbSet properties
    }
    
    public class SalesContext : BaseContext<SalesContext>
    {
    //DbSet properties
    }
    
  2. Create class called "BaseContect" and copy this code

    public class BaseContext<TContext>
        : DbContext where TContext : DbContext
    {
        static BaseContext()
        {
            //By setting it NULL, we are making it work with Existing Adventure Works database
            Database.SetInitializer<TContext>(null);
        }
        protected BaseContext()
            : base("name=AdventureWorksContext") //Points to Connection String in Config file
        { }
    }
    

This will help create multiple DbContext which targets one database, this is proper way to do it.

Upvotes: 1

DavidG
DavidG

Reputation: 118937

First of all there is no need to have a generic context. You can use the Set<> property of your context object. I would also not create the context object inside the repository. Instead pass it in the constructor as this will allow you to inject it in other ways, and reuse it in other projects later on.

So your repository could look like this:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private DbContext _context;

    public Repository(DbContext context)
    {
        _context = context;
    }

    public IQueryable<TEntity> All
    {
        get
        {
            return _context.Set<TEntity>();
        }
    }

}

You could even do this without having the repository as generic and instead just making the individual methods generic, for example:

public IQueryable<TEntity> All<TEntity> where TEntity : class
{
    get
    {
        return _context.Set<TEntity>();
    }
}

Upvotes: 2

Related Questions