首页 > 解决方案 > .NET Core 2.x 从 dbcontext 类中的 appsettings.json 获取连接字符串

问题描述

我的 DBContext 类中的设置连接字符串有问题。我知道我可以在 SqlLiteDbcontext 构造函数中注入 IConfiguration 或使用 IOption 模式,但在 CRUD.cs 中我已经使用无参数构造函数。我正在寻找不需要修改 CRUD.cs 的解决方案。

    public class SqliteDbContext : DbContext
    {
        public SqliteDbContext() : base()
        {
        }

        public SqliteDbContext(DbContextOptions<SqliteDbContext> options) : base(options)
        {
        }
 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=App_Data/sqlite.db");

            optionsBuilder.EnableSensitiveDataLogging(true);
        }

启动.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(IISDefaults.AuthenticationScheme);
            services.AddMemoryCache();
            services.AddMvc();
            // Adds services required for using options.
            //services.AddOptions();

            services.Configure<MvcOptions>(options =>
            {
            });

            services.AddDbContext<SqliteDbContext>(options =>
                options.UseSqlite(Configuration.GetConnectionString("Sqlite")));

CRUD.cs

 public partial class CRUD<T> where T : class, ICreatedDate, IId
    {
        private SqliteDbContext db;
        private DbSet<T> DbSet => db.Set<T>();

        public List<T> Read()
        {
            using (db = new SqliteDbContext())
            {
                return DbSet.ToList();
            }
        }
//...

标签: c#asp.net-mvcasp.net-core

解决方案


您不应该在 ASP.NET Core 中使用这样的实体框架。你有依赖注入和正确配置的 EF 上下文,所以你应该利用它。这基本上意味着:

  1. 永远不要使用new. 始终将上下文作为依赖项注入。
  2. 不要覆盖OnConfiguring数据库中的方法来配置上下文。配置应作为 传递DbContextOptions,因此上下文本身不负责设置配置。
  3. 避免为数据库上下文使用空的构造函数,以避免在上下文未配置的情况下误用。

所以你的代码应该是这样的:

public class SqliteDbContext : DbContext
{
    public SqliteDbContext(DbContextOptions<SqliteDbContext> options) : base(options)
    { }

    // define your database sets
    public DbSet<Entity> Entities { get; set; }
}

public class CRUDService<T>
{
    private readonly SqliteDbContext db;
    CRUDService(SqliteDbContext database)
    {
        db = database;
    }

    public List<T> Read()
    {
        return db.Set<T>().ToList();
    }
}

SqliteDbContext将由依赖注入容器自动提供。您只需要注入依赖项即可正确解析它。

顺便提一句。我通常建议您避免使用(通用)存储库模式。Entity Framework 中的数据库上下文已经是工作单元,每个数据库集已经是一个存储库。所以你可以直接使用它。在它之上添加另一个抽象,尤其是通用抽象,你几乎没有什么收获,因为这总是会限制你。

此外,您应该将您的重命名SqliteDbContext为实际描述上下文管理的数据的名称。上下文不应该关心正在使用的底层数据库提供程序。


推荐阅读