启动后访问DatabaseContext

时间:2018-12-08 12:10:00

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

我已经创建了一个基本的DatabaseContext来处理与SQLite数据库的通信:

public class DatabaseContext : DbContext
{
    public DbSet<GearComponent> GearComponents{ get; set; }

    public DatabaseContext() { }

    public DatabaseContext(DbContextOptions options) : base(options) { }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Filename = database.db");
        base.OnConfiguring(optionsBuilder);
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<GearComponent>().HasKey(m => m.Id);
        base.OnModelCreating(builder);
    }
}

我这样在DatabaseContext上注册了Startup.cs

services.AddDbContext<DatabaseContext>(options => options.UseSqlite("Filename=database.db"));

我使用以下命令创建了一个数据库:

  

dotnet ef迁移添加了testMigration

我还自动创建了一个控制器,以通过HTTP-GET / POST / PUT访问数据库。

此控制器获取DatabaseContext的实例:

public class GearComponentsController : ControllerBase
{
    private readonly DatabaseContext _context;

    public GearComponentsController(DatabaseContext context)
    {
        _context = context;
    }

    //...
}

GearComponentsController主要用于前端接收数据库条目。对于后端,我不想使用HTTP-POST / GET等,但是我想直接访问DatabaseContext-但是如何访问?

我在Program.cs中尝试过:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
        using (var db = new DatabaseContext())
        {
            db.GearComponents.Add(new GearComponent("Text", "Descr.", "08.12.2018"));
            db.SaveChanges();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

但是我的database.db从未收到此条目。

编辑:对于所有对我的解决方法感兴趣的人,请 here

3 个答案:

答案 0 :(得分:0)

如描述的文档中所述,方法CreateWebhostbuilder用于在构建主机和运行主机之间进行区别。 要运行主机意味着,之后的代码与throw语句之后的代码一样可访问。 试试这个:

public class Program
{
    public static void Main(string[] args)
    {
        //use var host to build the host
        var host = CreateWebHostBuilder(args).Build();
        using (var db = new DatabaseContext())
        {
            db.GearComponents.Add(new GearComponent("Text", "Descr.", "08.12.2018"));
            db.SaveChanges();
        }
        // Run host after seeding
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

编辑: 据我现在对您的问题的了解,您有一个前端,如果单击刷新按钮,则该前端应仅使用数据库的内容。 除此之外,您的后端还应该使用其他Web服务,并将使用的gearcomponent插入数据库中。 因此,您不希望其他应用程序执行该工作,这可能是Windows服务(易于处理更新数据库的时间间隔), 触发更新的唯一方法是从GearComponentsController或在actionFilter中启动它们。这样,您可以更新数据库并将数据提供给前端。希望性能无关紧要。

答案 1 :(得分:0)

由于您询问如何在控制器外部使用DatabaseContext来执行一些业务逻辑。您可以对repository pattern使用简单的方法。将仅演示用于插入数据。假设您已经创建了模型GearComponent,并且已经设置了EntityFramework。

创建包含接口和实现此接口的类的文件:

public interface IGearComponentRepository
{
  void Create(GearComponent obj)
}

public class GearComponentRepository : IGearComponentRepository
{
    private readonly DatabaseContext _context;
    public GearComponentRepository (DatabaseContext context)
    {
        _context = context;
    }

   public void Create(GearComponent data)
   {
      _context.Add(data);
      _context.SaveChanges();
   }
}

您需要通过IoC容器在您的Startup.cs文件中注册此服务

public void ConfigureServices(IServiceCollection services)
{
..
     services.AddMvc();
     services.AddTransient<IGearComponentRepository, GearComponentRepository>();
..
}

然后您可以在Controller中使用存储库

public class GearComponentsController : ControllerBase
{
private readonly IGearComponentRepository _gearComponentRepository;

public GearComponentsController(IGearComponentRepository 
_gearComponentRepository)
{
  _gearComponentRepository = gearComponentRepository;
}

[HttpPost]
public IActionResult Create(GearComponent data)
{
    _dataRepository.Create(data);

    return Ok();
}
}

答案 2 :(得分:0)

在program.cs中:

public static void Main(string[] args)
        {
            var hostBuilder = CreateWebHostBuilder(args);
            var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            if (!string.IsNullOrEmpty(env) && env.Equals("Production"))
            {
                hostBuilder.ConfigureLogging((context, builder) =>
                {
                    // Read GelfLoggerOptions from appsettings.json
                    builder.Services.Configure<GelfLoggerOptions>(context.Configuration.GetSection("Graylog"));

                    // Optionally configure GelfLoggerOptions further.
                    builder.Services.PostConfigure<GelfLoggerOptions>(options =>
                        options.AdditionalFields["machine_name"] = Environment.MachineName);

                    // Read Logging settings from appsettings.json and add providers.
                    builder.AddConfiguration(context.Configuration.GetSection("Logging"))
                        .AddConsole()
                        //.AddDebug()
                        .AddGelf();
                });
            }

            var host = hostBuilder.Build();

            using (var scope = host.Services.CreateScope())
            {
                try
                {
                    // Retrieve your DbContext isntance here
                    var dbContext = scope.ServiceProvider.GetRequiredService<NozomiDbContext>();

                    if (env != null && !env.Equals("Production"))
                    {
                        dbContext.Database.EnsureDeleted();
                        dbContext.Database.EnsureCreated();
                    }
                    else
                    {
                        dbContext.Database.SetCommandTimeout((int)TimeSpan.FromMinutes(10).TotalSeconds);
                        dbContext.Database.Migrate();
                    }
                    // place your DB seeding code here
                    //DbSeeder.Seed(dbContext);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex); 
                    // Continue
                }
            }

            host.Run();
        }

关注于:

using (var scope = host.Services.CreateScope())

var dbContext = scope.ServiceProvider.GetRequiredService<NozomiDbContext>();

您将能够像这样访问dbContext。