【问题标题】:Inject DbContextOptions vs DbContext in a repository EF Core在存储库 EF Core 中注入 DbContextOptions 与 DbContext
【发布时间】:2021-05-09 19:20:13
【问题描述】:

我有 StudentDbContext

public class StudentDbContext : DbContext
{
    public StudentDbContext()
    {
    }

    public StudentDbContext(DbContextOptions<StudentDbContext> options)
        : base(options)
    {

    }

    public virtual DbSet<Students> Students{ get; set; }

}

然后我有一个存储库,我尝试了解注入 StudentDbContext 与注入 DbContextOptions 有什么区别

注入 DbContextOptions

class StudentRepository : IStudentRepository
{
    private readonly DbContextOptions<StudentDbContext> _context;

    public StudentRepository(DbContextOptions<StudentDbContext> context)
    {
        _context = context;
    }
}

注入 StudentDbContext

class StudentRepository : IStudentRepository
{
    private readonly StudentDbContext _context;

    public StudentRepository(StudentDbContext context)
    {
        _context = context;
    }
}

每种情况有什么优点或缺点吗?

【问题讨论】:

    标签: asp.net-core .net-core entity-framework-core


    【解决方案1】:

    DbContextOptions 类用于创建 DbContext 使用的选项。它配置要用于数据库上下文的数据库(和其他选项)。 DbContext 类包含模型中每个实体的 DbSet 属性。 如果您尝试在存储库中使用 DbContextOptions,您将无法访问任何模型,因为它没有它们。

    【讨论】:

      【解决方案2】:

      DbContextOptionsDbContextOptions&lt;TContext&gt; 有不同的用例。

      您需要在DbContext 的子类型中注入DbContextOptions(通用或非通用)。 DbContextOptions 实例将包含您在 Startup 类中配置的选项:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddDbContextFactory<ConcreateDbContext>(
              options => options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test")
          );
      }
      

      如果您的 DbContext 实现不应该继承自,您将在您的 ConcreateDbContext 中注入选项类型 DbContextOptions&lt;ConcreateDbContext&gt; 的通用版本,这确保特定 DbContext 子类型的正确选项从依赖注入。您还可以将您的 ConcreateDbContext 标记为已密封,因为该类并非旨在继承自。

      public sealed class ConcreateDbContext: DbContext
      {
          public ConcreateDbContext(DbContextOptions<ConcreateDbContext> contextOptions)
              : base(contextOptions)
          {
          }
      }
      

      如果您想拥有一个打算从其继承的DbContext,您应该公开一个受保护的构造函数,它将以DbContextOptions 的非泛型版本作为参数。

      public class BaseDbContext: DbContext
      {
          protected BaseDbContext(DbContextOptions contextOptions)
              : base(contextOptions)
          {
          }
      }
      

      如果您想要一个既要实例化又要从其继承的DbContext,您将有两个构造函数,一个采用泛型版本,一个采用DbContextOptions 的非泛型版本。

      当您想与数据库中的数据进行交互时,您将注入具体的DbContext 实现(在您的情况下为StudentDbContext)。

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 1970-01-01
        • 2012-02-23
        • 2019-08-17
        • 2018-08-05
        • 2020-04-07
        • 2019-03-22
        • 2018-06-20
        • 2023-03-03
        相关资源
        最近更新 更多