public interface IDbContextFactory { DbContext CreateDbContext(string connectionString); } /// <summary> /// 这里实现的思路是根据用户输入的代码来决定链接的是哪个数据库,从而实现数据库多租户的方式 /// DbContextFactory 将能够在一个请求周期内创建并复用单个 DbContext 实例 /// </summary> public class DbContextFactory : IDbContextFactory { private readonly IServiceScopeFactory _scopeFactory; private DbContext _dbContext; public DbContextFactory(IServiceScopeFactory scopeFactory) { _scopeFactory = scopeFactory; } public DbContext CreateDbContext(string connectionString) { if (_dbContext != null) { return _dbContext; } if (string.IsNullOrEmpty(connectionString)) { throw new InvalidOperationException("链接字符串是空的..."); } var scope = _scopeFactory.CreateScope(); var optionsBuilder = new DbContextOptionsBuilder<NoteDbContext>(); optionsBuilder.UseMySql(connectionString, new MySqlServerVersion(new Version())); optionsBuilder.AddInterceptors(new LoggingInterceptor()); _dbContext = new NoteDbContext(optionsBuilder.Options); return _dbContext; } }
到这里我查了一些资料,得出了在.netcore中直接使用AddDbContext 与使用我封装的DbContextFactory 区别说明,如果有错误,请各位指正
/* 使用 AddDbContext 当使用 AddDbContext 方法注册 DbContext 时: 生命周期管理:ASP.NET Core DI 容器自动处理 DbContext 的生命周期。通常,DbContext 是作为 Scoped 服务注册的,这意味着每个 HTTP 请求都会创建一个新的 DbContext 实例,并且在请求结束时自动释放。 配置简化:AddDbContext 提供了一个地方来配置数据库连接和其他选项,使得配置更集中和一致。 集成:这种方式与 ASP.NET Core 的其他功能(如中间件、过滤器、控制器等)紧密集成,允许在这些组件中通过构造函数注入轻松获取 DbContext 实例。 连接池:对于某些数据库提供程序(如 SQL Server),AddDbContext 允许使用连接池(通过 AddDbContextPool 方法),这可以提高性能,因为它重用连接实例而不是每次都创建新的。 例子: builder.Services.AddDbContext<NoteDbContext>(options => options.UseMySql( builder.Configuration.GetConnectionString("YourConnectionStringName"), new MySqlServerVersion(new Version()) ) ); 使用 DbContextFactory 当手动创建 DbContextFactory 并使用它来创建 DbContext 实例时: 控制:对 DbContext 的创建有更多的控制,可以在需要的时候创建和释放 DbContext,而不是依赖于请求的生命周期。 灵活性:这种方法在某些特殊场景下很有用,比如在 Singleton 服务中需要使用 DbContext,或者在非 HTTP 请求的环境(如后台任务)中需要创建 DbContext。 手动管理:需要手动管理 DbContext 的生命周期,包括创建、使用和释放。 复杂性:相比于 AddDbContext,手动创建 DbContext 可能会增加代码的复杂性和出错的可能性。 例子: public class DbContextFactory : IDbContextFactory { // ... 实现 DbContextFactory 的代码 ... } builder.Services.AddScoped<IDbContextFactory, DbContextFactory>(); 总结 如果应用程序遵循标准的 ASP.NET Core 请求处理模式,并且希望利用框架提供的便利性和集成,那么使用 AddDbContext 是更好的选择。 如果需要在不同的环境中创建 DbContext,或者需要更细粒度的控制 DbContext 的创建和销毁,那么使用 DbContextFactory 可能更合适。 在大多数情况下,推荐使用 AddDbContext 方法,因为它简化了配置和管理,同时提供了与 ASP.NET Core 框架的紧密集成。只有在特定场景下,当标准方法不满足需求时,才考虑使用 DbContextFactory。 */
public class NoteDbContext : DbContext { public NoteDbContext(DbContextOptions<NoteDbContext> options) : base(options) { } public NoteDbContext(DbContextOptions<DbContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { /* 1.安装 Microsoft.EntityFrameworkCore.Proxies 包。 2.在 OnConfiguring 方法或在设置 DbContextOptionsBuilder 时调用 UseLazyLoadingProxies()。 3.导航属性必须是 virtual,这样代理才能重写它们。 4.实体类不能是 sealed,因为代理需要派生自它们。*/ /* 延迟加载可以使初始查询更快,因为它不会加载所有相关的数据。 然而,如果不当使用,它可能会导致 N+1 查询问题,这是指每次访问导航属性时都会执行一个新的数据库查询, 这可能会在不经意间导致大量的数据库请求,从而影响应用程序的性能。 因此,当使用延迟加载时,应该注意: 确保了解何时会触发延迟加载。 在性能敏感的代码路径中,可能需要显式地预加载(eager load)相关数据,以避免 N+1 查询问题。 监控和优化数据库查询,以确保应用程序的性能。*/ optionsBuilder.UseLazyLoadingProxies(); //base.OnConfiguring(optionsBuilder); } public DbSet<PrincipalInfo> PrincipalInfoDbSet { get; set; } }