EF Core 数据库更新的命令行连接字符串

38
使用ASP.NET Core和EF Core,我正在尝试将迁移应用到数据库。然而,在appsettings.json中的连接字符串的登录只有CRUD访问权限,因为安全方面的考虑,所以它无法创建表和列等内容。因此,当我运行以下命令时:
dotnet ef database update -c MyDbContextName -e Development

我想告诉它使用不同的连接字符串,但我不知道是否可以这样做?基本上,我想要使用两个不同的连接字符串,一个用于部署,另一个用于运行该应用程序。这可能吗?是否有更好的方法? 谢谢。

7个回答

52

6
如果有人遇到和我一样的问题,这里提供一下解决方法:--connection 可以解决问题,但你不仅需要更新命令行工具,还要把项目引用更新到 5.0+ 版本。 - Andrew
但是这对于迁移不起作用,对吗? - Daniel
@Daniel 试一下并在这里更新。 - Vivek Nuna
我尝试过,但对我没有用,所以我才会问。不管怎样,还是谢谢你 :) - Daniel
@Daniel 抱歉,我当时尝试了 EF Core 5,但之后就再也没能成功过。 - Vivek Nuna

21

将两个连接字符串都保留在appsettings.json中。从主上下文类继承一个子上下文类,并使用另一个连接字符串重写OnConfiguring

public class ScaffoldContext : MyDbContextName 
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string scaffoldConnStr = ConfigurationManager.ConnectionStrings["scaffoldConnStr"].ConnectionString;

        optionsBuilder.UseSqlServer(scaffoldConnStr);
    }
}

然后使用:

dotnet ef database update -c ScaffoldContext 

1
谢谢Ilya。我接受了你的答案,因为它是正确的,但你知道有没有一种方法可以不将其他连接字符串放在appsettings.json中,而是将其作为参数传递? - NP3
1
@NemanjaPerovic,不幸的是,dotnet ef database update没有提供覆盖连接字符串的选项。但是,您可以指定环境和DbContext选项,因此我建议这是最简单的更改connstr的方法。另一种方法可能是设置一个环境变量,然后在ScaffoldContext中读取它,但我从未尝试过,因为它看起来太棘手了。 - Ilya Chumakov
@IlyaChumakov 你能直接从Azure的暂存/生产环境运行该命令吗?我尝试过了,但是它抱怨找不到dotnet-ef。或者可以从本地机器上运行,利用指向远程暂存/生产数据库的连接字符串?TA - superjos
1
@superjos 我只是从本地机器使用了那个命令。你可以设置环境(开发、测试等)来覆盖脚手架上的连接字符串。 - Ilya Chumakov
1
@ChamikaSandamal 不是很确定 - 我想我们只是手动更新了一段时间的数据库,而且这个项目从来没有进展太多。 - NP3
显示剩余3条评论

6
在Linux终端中:
export ASPNETCORE_ENVIRONMENT="Development"
dotnet ef database update

当 ASPNETCORE_ENVIRONMENT 与 appsettings.Development.json 匹配并且连接字符串正确配置时。


6

如果您正在使用Package Manager Console,请使用以下命令:

Update-Database -Connection "YOUR_CONNECTION_STRING"


5

我喜欢利用脚手架的DbContext,但是我发现了一些问题(可能可以解决),同时也考虑到如何处理连接字符串的位置。这使我想到另一个更加简单的解决方案,所以我想在这里分享一下。

以下是关于这个通用方法和之后的解决方案:

  1. 我不喜欢将暂存/生产环境的连接字符串存储到源代码管理中。所以,我通过环境变量设置在临时命令窗口中传递(或者在命令行中动态传递,但我无法做到)。此时,如果我设置了环境变量,我也可以覆盖使用MyDbContextName的初始连接字符串,而不是添加新的连接字符串。因此,通过这种方式就能够克服整个脚手架DB上下文的问题了。

我在这个过程中遇到了其他问题:

  1. 初始DbContext需要将依赖项注入到构造函数中,那么子上下文也必须这样做。这使得dotnet ef命令会抱怨缺少无参数构造函数。

  2. 为了解决这个问题,在启动时,用.AddDbContext<ChildDbContext>(...)注册了子上下文。这还需要将ChildDbContext注入DbContextOptions<ParentDbContext>DbContextOptions<ChildDbContext>中。之后,dotnet ef仍然发现实例化ChildDbContext存在问题,因为它还需要依赖于IConfiguration,而这无法找到。也许这是由于dotnet-ef没有完全运行整个应用程序启动所致。

正如我所说的,我想这些问题最终可以解决,但是我仍然在质疑如果你不想将连接字符串保存在专用的appsettings文件中,脚手架上下文的真正价值是什么。一个反驳意见可能是,您可能会忘记设置远程连接字符串的环境变量,但是这时您只需在完成迁移后关闭命令窗口即可。希望对你有所帮助。


1
你可以将连接字符串添加到你的机密保险库中。我希望EF Core的更新数据库命令有-Connection参数(我使用PowerShell的Update-Database,它也缺少这个参数),但它只有-Context(或-c)开关,这迫使我们使用OnConfiguring,这非常笨拙。另外,我应该提到,如果你要部署到Azure,请在你的应用程序配置中设置一个“ConnectionString”设置,它可以通过Environment.GetVariable()读取。 - Chris Bordeman

2
我是这样解决的,受到Javier Colombera的答案的启发。
我在Windows的Bash终端上运行了以下命令,并获得了预期的结果:
export ASPNETCORE_ENVIRONMENT="Production"
export ConnectionStrings__DefaultConnection="SslMode=Prefer;TrustServerCertificate=true;Host=<value>;Port=<value>;Database=<value>;Username=<value>;Password=<value>"
dotnet ef database update

这可以避免在版本控制中存储生产数据库连接字符串,通过通过环境变量覆盖appsettings.json中的ConnectionStrings.DefaultConnection值来实现。
请注意,我的项目未为Staging和Production环境定义默认连接字符串,仅为本地Development环境定义了一个。

请问您能否指向列出所有可用键值选项的文档,例如ConnectionStrings.DefaultConnection。我很难找到它。 - fire_water

-6
dotnet ef database update --configuration Debug 

虽然这段代码可能回答了问题,但如果您添加一些关于“为什么”和“如何”的解释,对于OP和未来的读者来说会更有用。 - mousetail
当回答老问题或者已经有了充分的回答时,您应该解释一下您的回答对现有回答的补充。 - Gert Arnold
1
这并没有解决问题,也没有解释为什么你认为它应该这样做。 - Joep Beusenberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接