I had this problem in a project, since I don't want to give the whole domain scope, I've tried to simplify the classes as much as possible.
Basically I have a base class BaseClass, where two properties are referencing a a class that is Extending BaseClass => ClassA
It works if I remove ClassB.
It works if I remove one of the two references.
It works when I don't extend ClassA from the BaseClass
But not in this constellation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Threading;
namespace EFTestbed
{
public abstract class BaseClass
{
public int Id { get; set; }
public ClassA ClassA1 { get; set; }
public ClassA ClassA2 { get; set; }
}
public class ClassA : BaseClass
{
public string TitleA { get; set; }
}
public class ClassB : BaseClass
{
public string TitleB { get; set; }
}
public class Context : DbContext
{
public DbSet<ClassA> ClassAs { get; set; }
public DbSet<ClassB> ClassBs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ClassA>()
.HasOptional(e => e.ClassA1).WithOptionalDependent();
modelBuilder.Entity<ClassA>()
.HasOptional(e => e.ClassA2).WithOptionalDependent();
modelBuilder.Entity<ClassB>()
.HasOptional(e => e.ClassA1).WithOptionalDependent();
modelBuilder.Entity<ClassB>()
.HasOptional(e => e.ClassA2).WithOptionalDependent();
}
}
public class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("en-GB");
System.Console.WriteLine("Creating & Updating database...");
Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
using (var context = new Context())
{
context.ClassAs.Add(new ClassA() { TitleA = "Test1" });
System.Console.WriteLine(
string.Format("Number of objects written to the database: {0}",
context.SaveChanges()));
}
System.Console.Write("Press Enter to continue...");
System.Console.ReadLine();
}
}
}
I always get this Exception "Sequence contains more than one element"
How do I get it to work?
Here is the stack trace of the Exception:
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.ConfigureDependentBehavior(EdmAssociationType associationType, EdmModel model, EntityTypeConfiguration entityTypeConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.Configure(EdmNavigationProperty navigationProperty, EdmModel model, EntityTypeConfiguration entityTypeConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigureAssociations(EdmEntityType entityType, EdmModel model)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType entityType, EdmModel model)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel model)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(EdmModel model)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
at System.Data.Entity.DbSet`1.Add(TEntity entity)
at EFTestbed.Program.Main(String[] args) in d:\users\sasp1de\documents\visual studio 2010\Projects\EFTestbed\EFTestbed\TestEF\Program.cs:line 54
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
This is now fixed in the latest version of EF:
http://entityframework.codeplex.com/workitem/546
Related
How do I update this code below to allow for multiple DbContexts? I searched other posts and I tried to make my unit of work and dbfactory classes accept a generic type but I had trouble with the RepositoryBase class, the repository, the service and tying it all together; I still struggle with generics in C#. Can anyone help me out?
DbFactory.cs
public class DbFactory : Disposable, IDbFactory
{
WilMpeContext _dbContext;
public WilMpeContext Init()
{
return _dbContext ?? (_dbContext = new WilMpeContext());
}
protected override void DisposeCore()
{
_dbContext?.Dispose();
}
}
Disposable.cs
public class Disposable : IDisposable
{
private bool isDisposed;
~Disposable()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!isDisposed && disposing)
{
DisposeCore();
}
isDisposed = true;
}
// Ovveride this to dispose custom objects
protected virtual void DisposeCore()
{
}
}
iDbFactory.cs
public interface IDbFactory : IDisposable
{
WilMpeContext Init();
}
IRepository.cs
public interface IRepository<T> where T : class
{
// Marks an entity as new
void Add(T entity);
// Marks an entity as modified
void Update(T entity);
// Marks an entity to be removed
void Delete(T entity);
void Delete(Expression<Func<T, bool>> where);
// Get an entity by int id
T GetById(int id);
// Get an entity using delegate
T Get(Expression<Func<T, bool>> where);
// Gets all entities of type T
IEnumerable<T> GetAll();
// Gets entities using delegate
IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
}
IUnitOfWork.cs
public interface IUnitOfWork
{
void Commit();
}
RepositoryBase.cs
public abstract class RepositoryBase<T> where T : class
{
#region Properties
private WilMpeContext _dataContext;
private readonly IDbSet<T> _dbSet;
protected IDbFactory DbFactory
{
get;
private set;
}
protected WilMpeContext DbContext
{
get { return _dataContext ?? (_dataContext = DbFactory.Init()); }
}
#endregion
protected RepositoryBase(IDbFactory dbFactory)
{
DbFactory = dbFactory;
_dbSet = DbContext.Set<T>();
}
#region Implementation
public virtual void Add(T entity)
{
_dbSet.Add(entity);
}
public virtual void Update(T entity)
{
_dbSet.Attach(entity);
_dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
_dbSet.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = _dbSet.Where<T>(where).AsEnumerable();
foreach (T obj in objects)
_dbSet.Remove(obj);
}
public virtual T GetById(int id)
{
return _dbSet.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return _dbSet.ToList();
}
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).ToList();
}
public T Get(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).FirstOrDefault<T>();
}
#endregion
}
UnitOfWork.cs
public class UnitOfWork : IUnitOfWork
{
private readonly IDbFactory _dbFactory;
private WilMpeContext _dbContext;
public UnitOfWork(IDbFactory dbFactory)
{
this._dbFactory = dbFactory;
}
public WilMpeContext DbContext
{
get { return _dbContext ?? (_dbContext = _dbFactory.Init()); }
}
public void Commit()
{
DbContext.Commit();
}
}
WilMpeContext.cs - this is one of my DbContexts but now I need another and I'm not sure how to implement that with my existing design
public class WilMpeContext : IdentityDbContext<ApplicationUser>
{
public WilMpeContext()
: base("name=DefaultConnection", throwIfV1Schema: false) { }
public IDbSet<AppSetting> AppSettings { get; set; }
//the rest of the tables were removed for brevity
public virtual void Commit()
{
base.SaveChanges();
}
public static WilMpeContext Create()
{
return new WilMpeContext();
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Here is how I setup the repository to use the unit of work. AppSetting is a table in my model:
public interface IAppSettingRepository : IRepository<AppSetting>
{
void UpdateAppSetting(AppSetting appSetting);
}
public class AppSettingRepository : RepositoryBase<AppSetting>,IAppSettingRepository
{
public AppSettingRepository(IDbFactory dbFactory)
: base(dbFactory) { }
//an example of how I do something in the database. See I use DbContext from RepositoryBase
public void UpdateAppSetting(AppSetting appSetting)
{
DbContext.Entry(appSetting).State = EntityState.Modified;
}
}
And this is my service:
public class AppSettingService : IAppSettingService
{
private readonly IAppSettingRepository _appSettingRepository;
private readonly IUnitOfWork _unitOfWork;
public AppSettingService(IAppSettingRepository appSettingRepository,
IUnitOfWork unitOfWork)
{
_appSettingRepository = appSettingRepository;
_unitOfWork = unitOfWork;
}
//call repository to do database stuff and then commit changes
public void UpdateAppSetting(AppSetting appSetting)
{
_appSettingRepository.UpdateAppSetting(appSetting);
_unitOfWork.Commit();
}
}
You need to make all your interfaces and classes that is using your current WilMpeContext to generic. Also you would need to put a generic constraint on new generic.
First make your Interfaces generic for Unit of work and DBFactory:
public interface IUnitOfWork<TContext> where TContext: DbContext, new()
{
void Commit();
}
public interface IDbFactory<TContext> : IDisposable where TContext: DbContext, new()
{
TContext Init();
}
Now let's update your Classes for UnitOfWork and DBFactory:
public class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext: DbContext, new()
{
private readonly IDbFactory<TContext> _dbFactory;
private TContext _dbContext;
public UnitOfWork(IDbFactory<TContext> dbFactory)
{
this._dbFactory = dbFactory;
}
public TContext DbContext
{
get { return _dbContext ?? (_dbContext = _dbFactory.Init()); }
}
public void Commit()
{
this.DbContext.SaveChanges();
}
}
public class DbFactory<TContext> : Disposable, IDbFactory<TContext> where TContext: DbContext, new()
{
TContext _dbContext;
public TContext Init()
{
return _dbContext ?? (_dbContext = new TContext());
}
protected override void DisposeCore()
{
_dbContext?.Dispose();
}
}
Add an additional generic on Repository base class:
public abstract class RepositoryBase<T, TContext> where T : class where TContext: DbContext, new()
{
#region Properties
private TContext _dataContext;
private readonly IDbSet<T> _dbSet;
protected IDbFactory<TContext> DbFactory
{
get;
private set;
}
protected TContext DbContext
{
get { return _dataContext ?? (_dataContext = this.DbFactory.Init()); }
}
#endregion
protected RepositoryBase(IDbFactory<TContext> dbFactory)
{
DbFactory = dbFactory;
_dbSet = DbContext.Set<T>();
}
#region Implementation
public virtual void Add(T entity)
{
_dbSet.Add(entity);
}
public virtual void Update(T entity)
{
_dbSet.Attach(entity);
_dataContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
public virtual void Delete(T entity)
{
_dbSet.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = _dbSet.Where<T>(where).AsEnumerable();
foreach (T obj in objects)
_dbSet.Remove(obj);
}
public virtual T GetById(int id)
{
return _dbSet.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return _dbSet.ToList();
}
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).ToList();
}
public T Get(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).FirstOrDefault<T>();
}
#endregion
}
Here is your repository that will be typed with your Actual Context WilMpeContext class.
public class AppSettingRepository : RepositoryBase<AppSetting, WilMpeContext>, IAppSettingRepository
{
public AppSettingRepository(IDbFactory<WilMpeContext> dbFactory)
: base(dbFactory) { }
//an example of how I do something in the database. See I use DbContext from RepositoryBase
public void UpdateAppSetting(AppSetting appSetting)
{
DbContext.Entry(appSetting).State = System.Data.Entity.EntityState.Modified;
}
}
Finally your AppsettingService
public class AppSettingService : IAppSettingService
{
private readonly IAppSettingRepository _appSettingRepository;
private readonly IUnitOfWork<WilMpeContext> _unitOfWork;
public AppSettingService(IAppSettingRepository appSettingRepository,
IUnitOfWork<WilMpeContext> unitOfWork)
{
_appSettingRepository = appSettingRepository;
_unitOfWork = unitOfWork;
}
//call repository to do database stuff and then commit changes
public void UpdateAppSetting(AppSetting appSetting)
{
_appSettingRepository.UpdateAppSetting(appSetting);
_unitOfWork.Commit();
}
}
Now your UnitOfWork infrastructure will support any DbContext for all repositories.
Udpate
Alternative solution(May be)
May be I'm wrong but why would you need multiple dbcontext if your dbContext is not shared across the applications. I'm sure you are using Asp.net 5 MVC project that generates it's own IdenityDbContext and you might have your other DBContext as well. You can merge these two context and this way you can keep your current implementation of UOW.
Check out these SO QnA if this is the actual problem.
ASP.NET Identity DbContext confusion
Merge MyDbContext with IdentityDbContext
In my project, I'm using EF Code First approach following Code Camper structure. So i have generic repository IRepository;
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(int id);
}
and then it's implementation EFRepository<T>
public class EFRepository<T> : IRepository<T> where T : class
{
public EFRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public virtual IQueryable<T> GetAll()
{
return DbSet;
}
public virtual T GetById(int id)
{
//return DbSet.FirstOrDefault(PredicateBuilder.GetByIdPredicate<T>(id));
return DbSet.Find(id);
}
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
public virtual void Update(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
DbSet.Attach(entity);
}
dbEntityEntry.State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
DbSet.Attach(entity);
DbSet.Remove(entity);
}
}
public virtual void Delete(int id)
{
var entity = GetById(id);
if (entity == null) return; // not found; assume already deleted.
Delete(entity);
}
}
Based on customer needs, i should not delete any DB records, so for most(not all of them) tables I have isDeleted property to mark record as deleted. And these records which marked as isDeleted should not appear to users
My question is: How in my generic repository implementation check for that isDeleted property while I'm expecting generic object T.
For example GetAll function should be:
public virtual IQueryable<T> GetAll()
{
return DbSet.where(x=>x.isDelete == false);
}
Any ideas, how i can do that?
Create an interface with IsDeleted property and inherit all your models from it. Then you could modify your repository like this:
public class EFRepository<T> : IRepository<T> where T : TypeOfYourNewInterface
Now you can access IsDeleted in generic methods.
I could not find a suitable solution to my problem. After more searching i ended with 3 solutions:
Create extension methods.
Create a custom IDbSet which can accept a filter expression.
Add a discriminator to every model.
I choosed solution(3) although, I don't like it much
Using Autofac, I tried to use my generic type :
public interface IRepository<T> where T : class
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(Expression<Func<T, bool>> where);
T GetById(long Id);
T GetById(string Id);
T Get(Expression<Func<T, bool>> where);
IEnumerable<T> GetAll();
IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
}
to register my generic class :
public abstract class RepositoryBase<T> where T : class
{
private iMOSSContainer dataContext;
private readonly IDbSet<T> dbset;
protected RepositoryBase()
{
DatabaseFactory = new DatabaseFactory();
dbset = DataContext.Set<T>();
}
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected iMOSSContainer DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
dbset.Add(entity);
}
public virtual void Update(T entity)
{
dbset.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
dbset.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
foreach (T obj in objects)
dbset.Remove(obj);
}
public virtual T GetById(long id)
{
return dbset.Find(id);
}
public virtual T GetById(string id)
{
return dbset.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
}
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return dbset.Where(where).ToList();
}
public T Get(Expression<Func<T, bool>> where)
{
return dbset.Where(where).FirstOrDefault<T>();
}
}
this way :
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(RepositoryBase<>)).As(typeof(IRepository<>)); //.InstancePerLifetimeScope();
Container = builder.Build();
And returns an error "sequence contains no element" when building a container.
Did i do something wrong with the code? I already tried to search for an answer to no avail. So, your help would be pretty much appreciated.
Ok, then i changed the RepositoryBase class like this :
public class RepositoryBase<T> : IRepository<T> where T : class
{
private iMOSSContainer dataContext;
private readonly IDbSet<T> dbset;
public RepositoryBase()
{
DatabaseFactory = new DatabaseFactory();
dbset = DataContext.Set<T>();
}
So :
i use the "iRepository" interface (and move the "where T : class"
statement at the end of the line)
i remove the "abstract" class (because it leads to another error)
set the default constructor to "public" (because it leads to another
error, as well)
And everything is working good right now.
Your RepositoryBase type is abstract, therefore it can't be registered. You need to register non-abstract types. I'm guessing what you're intending to do is register all subtypes of RepositoryBase.
I Use UnitOfWork Pattern with Entity Framework to expose DbContext using bellow code. So My question is that, is it poosible to get Context instance with Ninject ?
IUnitOfWork
public interface IUnitOfWork<C> : IDisposable
{
int Commit();
C GetContext { get; set; }
}
UnitOfWork
public class UnitOfWork<C> : IUnitOfWork<C> where C : DbContext
{
private bool _disposed;
private readonly C _dbContext = null;
public UnitOfWork()
{
GetContext = _dbContext ?? Activator.CreateInstance<C>();
}
public int Commit()
{
return GetContext.SaveChanges();
}
public C GetContext
{
get;
set;
}
[...]
Now within NinjectWebCommon
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>().InRequestScope();
kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>();
}
Without using _dbContext ?? Activator.CreateInstance<C>(); , can it be possible to get DbContext instance via Ninject ?
Yes it is possible . check the solution bellow
Ninject DI Configuration
kernel.Bind<MyDbContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>();
kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>();
And within UnitOfWork
public class UnitOfWork<C> : IUnitOfWork<C> where C : DbContext
{
private readonly C _dbcontext;
public UnitOfWork(C dbcontext)
{
_dbcontext = dbcontext;
}
public int Commit()
{
return _dbcontext.SaveChanges();
}
public C GetContext
{
get
{
return _dbcontext;
}
}
[...]
I am trying to work with generic repositories in entity framework and came across this code below:
public class GenericRepository<TContext, TEntity> : IGenericRepository<TEntity>
where TContext : IUnitOfWork
where TEntity : class
{
protected TContext _context;
/// <summary>
/// Constructor that takes a context
/// </summary>
/// <param name="context">An established data context</param>
public GenericRepository(TContext context)
{
_context = context;
}
public IQueryable<TEntity> Select()
{
return _context.Set<TEntity>().AsQueryable();
}
public IEnumerable<TEntity> GetAll()
{
return _context.Set<TEntity>().AsEnumerable();
}
public IEnumerable<TEntity> Where(Func<TEntity, bool> predicate)
{
return _context.Set<TEntity>().Where(predicate);
}
public TEntity GetSingle(Func<TEntity, bool> predicate)
{
return _context.Set<TEntity>().Single(predicate);
}
public TEntity GetFirst(Func<TEntity, bool> predicate)
{
return _context.Set<TEntity>().First(predicate);
}
public void Add(TEntity entity)
{
if (entity == null)
throw new ArgumentException("Cannot add a null entity");
_context.Set<TEntity>().Add(entity);
}
public void Delete(TEntity entity)
{
if (entity == null)
throw new ArgumentException("Cannot delete a null entity");
_context.Set<TEntity>().Remove(entity);
}
public void Attach(TEntity entity)
{
if (entity == null)
throw new ArgumentException("Cannot attach a null entity");
_context.Set<TEntity>().Attach(entity);
}
#region IDisposable implementation
private bool disposedValue;
public void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// dispose managed state here if required
}
// dispose unmanaged objects and set large fields to null
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
However I find it a little difficult to understand the need for the constructor created
/// <summary>
/// Constructor that takes a context
/// </summary>
/// <param name="context">An established data context</param>
public GenericRepository(TContext context)
{
_context = context;
}
Can someone please explain the use of this?
Thanks
That's because there may be multiple DbContext class in your project, So you need to inject a specific DbContext instance to tell the GenericRepository class which DbContext you are using.
The reason you need to have multiple DbContext class maybe are:
Your project target to several Databases;
Your project is large, for the consideration of performance and maintainability, you want to split it into several modules. For Example:
public class BaseContext<TContext> : DbContext
where TContext : DbContext, new()
{
protected BaseContext()
: base("name=ConnectionString")
{
}
}
public class ShopDbContext :BaseContext<ShopDbContext>
{
public DbSet<Product> Products{ get; set; }
}
public class BlogDbContext :BaseContext<BlogDbContext>
{
public DbSet<Blog> Blogs{ get; set; }
}
Now, if you want to query the Products, you must instantiate the ShopDbContext, and pass it into the GenericRepository constructor(IoC is a good choice).