Reputation: 3299
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
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
Create DbContext(generic one in your case)
public class HumanResourceContext : BaseContext<HumanResourceContext>
{
//DbSet properties
}
public class SalesContext : BaseContext<SalesContext>
{
//DbSet properties
}
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
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