.NET Core 2.x从dbcontext类中的appsettings.json获取连接字符串

时间:2018-11-16 11:24:51

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

我在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);
        }

Startup.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();
            }
        }
//...

1 个答案:

答案 0 :(得分:2)

您不应在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重命名为实际上描述上下文管理的数据的名称。上下文不应该关心正在使用什么基础数据库提供程序。