我有以下两个项目的解决方案:
在类库中,我有一个这样的dbcontext:
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
在Web应用程序中,我在Startup.cs文件中使用以下几行将dbcontext注册为服务
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
这时我可以在两个项目中使用dbcontext了。现在,在不更改类库的情况下,我想为同一个数据库定义新表,因此我在Web应用程序项目中创建了一个新的dbcontext,该继承自我在类库中拥有的dbcontext。
public class ExtendedApplicationDbContext : ApplicationDbContext
{
public ExtendedApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
}
我更新了Startup.cs文件,以便我也注册新的dbcontext,以便可以在Web应用程序中使用Products表。
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
services.AddDbContext<ExtendedApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ApplicationDbContextConnection")));
现在我可以在两个项目中都使用ApplicationDbContext,但是当我尝试在Web应用程序中使用ExtendedApplicationDbContext时,会发生一些奇怪的事情。
我可以读取数据,但是所做的所有更改都不会更新数据库。
我尝试解释一下,但找不到解决问题的方法。 有人可以帮助我了解我的代码有什么问题吗?
答案 0 :(得分:2)
EF上下文保留对象缓存和内部更改跟踪。具有两个引用同一数据库的单独上下文将不可避免地导致同步问题,这将导致一个上下文掩盖另一上下文正在执行的操作,反之亦然。简而言之,每个数据库应该只有一个 active 上下文。
我指定 active 是因为可以使用“有界”上下文,在这种情况下,您实际上具有多个确实连接到同一数据库的上下文,但是这样的上下文只能处理一个子集数据库中对象的数量,没有重叠。例如,您可能有一个用于与客户合作的上下文,一个用于与产品合作的上下文,但是在这两者之间应该没有交叉,即“产品”上下文不应以任何方式(甚至仅仅是关系)引用客户,反之亦然。
长短不一,这不是正确的路径。首先,RCL和Web应用程序都不应具有上下文。它应该在另一个类库中,然后可以在其他两个项目之间共享。而且,Web应用程序层不应对数据层进行任何模式更改,因为该数据层正被其他事物使用。这是一个用脚射击自己的好方法。将数据层的内容保留在数据层中。