Reputation: 2983
I have a solution with the following two projects:
In the class library I have a dbcontext like this:
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
In the web application I register the dbcontext as a service using the following lines in my Startup.cs file
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
At this point I can use the dbcontext in both projects. Now, without changing the class library I want to define new tables for the same database so I created a new dbcontext in the web application project which inherits from the one that I have in the class library.
public class ExtendedApplicationDbContext : ApplicationDbContext
{
public ExtendedApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
}
I update my Startup.cs file so that I will register the new dbcontext as well so that I will be able to use the Products table in the web application.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
services.AddDbContext<ExtendedApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
Now I can use ApplicationDbContext in both projects but when I try to use the ExtendedApplicationDbContext in the web application, something strange happens.
I can read the data but all the changes that I make do not update the database.
I try to explain it but I can not find a way to solve the problem. Can someone help me understand what is wrong with my code?
Upvotes: 1
Views: 888
Reputation: 239460
EF contexts keeps an object cache and internal change-tracking. Having two separate contexts referencing the same database will inevitably lead to sync issues which will then cause one context to clobber what the other context is doing and vice versa. In short, you should have one and only one active context per database.
I specify active because it's okay to use "bounded" contexts, where you'd have multiple contexts that do in fact connect to the same database, but such contexts should only then deal with a subset of the objects in the database, with no overlap. For example, you might have one context for working with Customers and one for working with Products, but there should then be no cross-over between the two, i.e. the "Products" context should not in any way (even by just mere relation) reference a customer, and vice versa.
Long and short, this is not the correct path. For one, neither the RCL nor the web application should have the context. It should be in a different class library that can then be shared between the two other projects. Also, the web application layer should not make any schema changes to the data layer, as that data layer is being used by other things. That's a good way to shoot yourself in the foot. Keep the data layer stuff with the data layer.
Upvotes: 1