Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该把Database.com放在哪里?_C#_Asp.net_Entity Framework Core - Fatal编程技术网

C# 我应该把Database.com放在哪里?

C# 我应该把Database.com放在哪里?,c#,asp.net,entity-framework-core,C#,Asp.net,Entity Framework Core,我有一个Entity Framework Core+ASP.NET Core应用程序,当我的应用程序启动时,我希望确保创建数据库,并最终(一旦进行迁移)确保这些数据库也运行 最初,我将Database.EnsureCreated()放入我的DbContext的构造函数中,但每次有人点击我的应用程序时,它都会运行,因为每次都会创建一个新的DbContext实例 我试图将其放入我的启动代码中,但我需要一个DbContext的实例来实现这一点,并且不清楚如何准确地获得一个实例。我将EF配置为: ser

我有一个Entity Framework Core+ASP.NET Core应用程序,当我的应用程序启动时,我希望确保创建数据库,并最终(一旦进行迁移)确保这些数据库也运行

最初,我将
Database.EnsureCreated()
放入我的
DbContext
的构造函数中,但每次有人点击我的应用程序时,它都会运行,因为每次都会创建一个新的
DbContext
实例

我试图将其放入我的启动代码中,但我需要一个
DbContext
的实例来实现这一点,并且不清楚如何准确地获得一个实例。我将EF配置为:

serviceCollection.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<Models.MyContext>(options => options.UseSqlServer(...));
servicecolection.AddEntityFramework()
.AddSqlServer()文件
.AddDbContext(options=>options.UseSqlServer(…);
我看不到从服务集合中获取DbContext实例的方法,也看不到任何合适的单例可以将DbContext注入其中以便进行一次性初始化


那么,确保每次应用程序运行时调用一次与my DbContext相关的代码的最佳位置是什么呢?

在撰写本文时,没有一个“正确”的位置在应用程序启动时运行代码,使其在请求范围内执行(请参阅)

目前,解决方法是执行以下操作,但在更复杂的多应用程序场景中不起作用(请参阅)

公共类启动
{
...
公共无效配置(IAApplicationBuilder applicationBuilder,…)
{
...
//注意:这必须在配置结束时进行
var serviceScopeFactory=applicationBuilder.ApplicationServices.GetRequiredService()
使用(var serviceScope=serviceScopeFactory.CreateScope())
{
var dbContext=serviceScope.ServiceProvider.GetService();
dbContext.Database.recreated();
}
}
}

我想知道您为什么要运行一个接一个的重新创建,作为服务的一部分。是否确实希望Web服务器创建或更新数据库架构?如果数据库不是最新的,为什么Web服务器会启动并服务于请求

您真的非常信任迁移,以至于执行迁移时不会破坏数据,也不想在运行迁移后测试数据吗

此外,这将要求您授予Web服务器数据库用户更改数据库架构的权限。这本身就是一个漏洞—接管您的Web服务器的人将能够修改您的数据库架构


我建议您在自己运行的小型实用程序中创建数据库并应用迁移,而不是作为web应用程序的一部分

我认为
zmbq
的建议是正确的,有一种方法可以确保迁移与部署一起运行,从而使用Visual Studio的发布功能同步二进制文件和数据库更改

针对IIS实例发布时,可以指定目标数据库连接字符串,以用于运行所需的迁移:


这将确保仅在需要时(而不是每次应用程序启动时)应用更改,并且应用程序运行时使用最少需要的数据库权限(即数据库编写器、读取器等),而不是更改表的权限,创建索引等。

我感谢您反对在应用程序中创建/迁移的论点。对于企业级应用程序,我倾向于在所有方面都同意您的意见。然而,对于一个小型初创企业规模的服务来说,在应用程序内部创建/迁移可以极大地简化部署、测试、迁移、管理、调试等。我相信,在实现MVP时,冒额外的风险是值得的。一旦服务充分增长,就可以考虑提取数据库创建/迁移。在我的情况下,我的客户是基于Linux的程序员,他希望通过编辑配置文件来切换数据库服务器。他将处理克隆和那些。如果没有EnsureCreated,他必须安装所有工具来运行更新数据库。有一个很好的
Migrate
实用程序可以做到这一点。当使用内存中的DB或在测试期间,这是一个非常有效的工具。EnsureCreated用于测试,而不是用于生产Hey Micah,我同意你的观点,因为我也看到了github的3070版,但是你不能直接将
MyDbContext
注入到你的
Configure()
方法中吗?我相信我只是从github的版本中复制了这个。可能有更好的方法,但我认为作者(作为一名EF开发人员)知道什么是最好的,所以我只是复制了他们的解决方案。配置是在DI初始化之前还是之后运行?也许您从
serviceScopeFactory
获得的dbContext与您从DI获得的dbContext有所不同?如果您找到了比此更好的解决方案,请随时在此处提交编辑或评论。:)只是检查一下,我还声称对这个话题一无所知:)我至少回答了两个问题()断言DI直接进入配置()是如何做到的,也许有人会告诉我为什么我错了,或者他们有什么不同。谢谢,我不知道这是否适用于早期版本,对我来说,它说在DI容器上找不到MyDbContext。我认为这是在ConfigureServices之前执行的,或者是并行执行的。
public class Startup
{
    ...

    public void Configure(IApplicationBuilder applicationBuilder, ...)
    {
        ...
        // NOTE: this must go at the end of Configure
        var serviceScopeFactory = applicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
        using (var serviceScope = serviceScopeFactory.CreateScope())
        {
            var dbContext = serviceScope.ServiceProvider.GetService<MyDbContext>();
            dbContext.Database.EnsureCreated();
        }
    }
}