有没有办法从已发布的 DLL 中获取 运行 EF Core RC2 工具?
Is there a way to run EF Core RC2 tools from published DLL?
发布 .Net Core RC1 应用程序后,project.json 中指定的命令已为其创建相应的 .cmd 文件,可以在部署后执行(例如 web.cmd 和 ef.cmd ).在我的例子中,我想在我的部署目标上 运行 以下 Entity Framework 命令:
dotnet ef database update -c MyContext
当我从包含源代码的文件夹中 运行 时,这工作正常,但是在发布之后,它似乎没有在编译的 DLL 中找到命令。我对 RC2 命令变化的理解是 'tools' 可以编译为名为 dotnet-*.dll 的独立应用程序,并且可以通过 CLI 执行。 Entity Framework 核心工具如何在发布的输出中作为可执行 DLL 公开?
仅供参考,我的 build/deployment 工作流程如下:
TeamCity
dotnet restore => dotnet build => dotnet test => dotnet publish
章鱼部署
上传包 => EF 更新数据库 => 等
我在一个项目中遇到了同样的问题,但出于多种原因,我不希望在应用程序启动时自动迁移到 运行。
为了解决这个问题,我更新了 Program.cs
以接受两个参数(下面列出了完整代码)
--ef-migrate
,应用所有挂起的迁移,并且
--ef-migrate-check
,以验证是否已应用所有迁移
如果存在参数,则应用 EF 操作并退出程序,否则启动 Web 应用程序。
请注意,它依赖于 Microsoft.Extensions.CommandLineUtils
包来简化命令行解析。
对于章鱼部署,然后可以将包发布两次到不同的位置 - 一次用于 运行ning 迁移,另一次用于虚拟主机。在我们的例子中,我们添加了一个“post 部署 powershell 脚本”,内容为
$env:ASPNETCORE_ENVIRONMENT="#{Octopus.Environment.Name}"
dotnet example-app.dll --ef-migrate
在 docker 上下文中 它也可以完美工作
docker run -it "example-app-container" dotnet example-app.dll --ef-migrate
完全 Program.cs 不包括命名空间和使用:
//Remember to run: dotnet add package Microsoft.Extensions.CommandLineUtils
public class Program
{
public static void Main(string[] args)
{
var commandLineApplication = new CommandLineApplication(false);
var doMigrate = commandLineApplication.Option(
"--ef-migrate",
"Apply entity framework migrations and exit",
CommandOptionType.NoValue);
var verifyMigrate = commandLineApplication.Option(
"--ef-migrate-check",
"Check the status of entity framework migrations",
CommandOptionType.NoValue);
commandLineApplication.HelpOption("-? | -h | --help");
commandLineApplication.OnExecute(() =>
{
ExecuteApp(args, doMigrate, verifyMigrate);
return 0;
});
commandLineApplication.Execute(args);
}
private static void ExecuteApp(string[] args, CommandOption doMigrate, CommandOption verifyMigrate)
{
Console.WriteLine("Loading web host");
//
// Please note that this webHostBuilder below is from an older
// dotnet core version. Newer dotnet cores have a simplified version
// Use that instead and just take the command line parsing stuff with you
var webHost = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
if (verifyMigrate.HasValue() && doMigrate.HasValue())
{
Console.WriteLine("ef-migrate and ef-migrate-check are mutually exclusive, select one, and try again");
Environment.Exit(2);
}
if (verifyMigrate.HasValue())
{
Console.WriteLine("Validating status of Entity Framework migrations");
using (var serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DatabaseContext>())
{
var pendingMigrations = context.Database.GetPendingMigrations();
var migrations = pendingMigrations as IList<string> ?? pendingMigrations.ToList();
if (!migrations.Any())
{
Console.WriteLine("No pending migratons");
Environment.Exit(0);
}
Console.WriteLine("Pending migratons {0}", migrations.Count());
foreach (var migration in migrations)
{
Console.WriteLine($"\t{migration}");
}
Environment.Exit(3);
}
}
}
if (doMigrate.HasValue())
{
Console.WriteLine("Applyting Entity Framework migrations");
using (var serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DatabaseContext>())
{
context.Database.Migrate();
Console.WriteLine("All done, closing app");
Environment.Exit(0);
}
}
}
// no flags provided, so just run the webhost
webHost.Run();
}
}
有一个非常有用的 post 解决了这个问题 here。
它对我有用(我不得不稍微调整一下命令,但它为我提供了良好的入门基础)。
总之:您可以通过传递 ef.dll
来复制 dotnet ef database update
命令(例如,直接从您的 nuget 文件夹(或者如果您没有 nuget,则从其他地方复制,因为您在一台生产机器..)),你的 .dll 包含带有一些附加参数(见下文)到 dotnet.exe
(或 linux 等价物)的迁移。
为完整起见,这里是 .cmd(也来自博客post!)
set EfMigrationsNamespace=%1
set EfMigrationsDllName=%1.dll
set EfMigrationsDllDepsJson=%1.deps.json
set DllDir=%cd%
set PathToNuGetPackages=%USERPROFILE%\.nuget\packages
set PathToEfDll=%PathToNuGetPackages%\microsoft.entityframeworkcore.tools.dotnet.0.0\tools\netcoreapp1.0\ef.dll
dotnet exec --depsfile .\%EfMigrationsDllDepsJson% --additionalprobingpath %PathToNuGetPackages% %PathToEfDll% database update --assembly .\%EfMigrationsDllName% --startup-assembly .\%EfMigrationsDllName% --project-dir . --content-root %DllDir% --data-dir %DllDir% --verbose --root-namespace %EfMigrationsNamespace%
(一个bash版本如果这个cmd在博客里post)
顺便说一句。许多 github 问题中也提到了这种方法:https://github.com/aspnet/EntityFramework.Docs/issues/328
https://github.com/aspnet/EntityFramework.Docs/issues/180
ps:我在 blog of Ben Day 中找到了这个,所以所有功劳归于 Ben!
不幸的是,EF Core 迁移很糟糕,很多... 我已经看到了很多解决方案,但让我们列一个清单。因此,这里是您可以对 运行 执行的操作,并在没有 Visual Studio 的情况下部署 EF 迁移。下面的None是完美的解决方案都有一些注意事项:
- 使用 EF Core Tools here 是一个 link 官方 MS 站点,其中解释了如何安装和使用它。
- 优点:微软官方工具。所有版本的 .NET Core 都支持。
- 缺点:好像是EF6“Migrate.exe”的继承者。 但事实并非如此!目前,如果没有实际的源代码 (.csproj),则无法使用此工具。这不太适合 Live/Prod 部署。通常您的数据库服务器上没有 C# 项目。
- dotnet exec 我试图理解大量记录不完整的参数。并且未能 运行 迁移,直到找到 this script。这个名字暗示了 .NET 核心 2.1,但我已经将它与 3.0 一起使用并且工作了。 更新:没有 运行 它与 .NET 5
- 优点:可以像EF6“migrate.exe”一样使用。最后迁移工作没有源代码。这很可能是从脚本和使用程序集进行迁移的唯一方法。
- 缺点: 设置脚本非常困难,容易遗漏一个参数。没有真正记录解决方案,可能会将 .NET Core 版本更改为版本。此外,您很可能还需要更改代码。您必须实现
IDesignTimeDbContextFactory<DbContext>
接口才能使其工作。还要确保您的部署服务器上有 EF.dll 和 Microsoft.EntityFrameworkCore.Design.dll。 linked 脚本正在许多文件夹中寻找那些。最好是在构建期间将其从您的 .nuget 文件夹复制到您的工件。听起来很复杂,是的......但是 linked 脚本很有帮助。
- 将 EF 迁移添加到您的 Startup.cs 或代码开始 运行ning 并有权访问 DBContext 的任何位置。使用
dbContext.Database.Migrate();
- 优点:迁移每次都会自动发生,无需执行任何其他操作。
- 缺点:迁移每次都会自动发生...您可能不希望发生的问题。 它还会在每次应用程序启动时 运行。所以你的启动时间会很糟糕。
- Custom app. 与前面的解决方案(第3点)类似。因此,您使用 .NET 代码来 运行 迁移。但与其将其放入您的应用程序,不如创建一个小型控制台应用程序 并在其中调用 migrate。您必须构建此应用程序并在部署期间将其放入工件 运行。
- 优点:不涉及脚本。您可以随时在部署管道中调用它。所以你真正的应用程序启动时间不会受到影响。
- 缺点:您必须维护、构建和打包应用程序才能执行 EF Core 迁移。
- 如果您使用 Azure Devops 进行部署,则可以使用 extension like this。或者只搜索 Azure Devops Marketplace。
- 优点:它应该可以工作 :) 没有尝试过它们中的任何一个,也不知道它们的作用。 (我很确定他们也在使用 'dotnet exec' 第 2 点。)
- 缺点:并非每个人都可以从 Azure Devops 访问 Live/Prod。
- 生成SQL脚本:如果none以上的工作你可以生成迁移SQL和运行它之后。 运行 带有“脚本”参数的 EF 工具:
dotnet ef migrations script --output <pathAndFile>.sql --context <DbContextName> --idempotent
。输出是一个 SQL 文件,可以手动执行或通过 CI/CD 管道中的脚本执行。
- 优点:如果您没有访问或模式更改权限来生产仅生产数据库的 DBA,那么这是一个完美的解决方案。您可以向 DBA 提供“安全可靠”的 SQL 文件 运行...
- 缺点:强调此解决方案非常重要必须运行在您的
.csproj
文件所在的工作目录中。所以它需要源代码! 此外,您还必须稍微更改一下代码。需要执行 IDesignTimeDbContextFactory<DbContext>
.
更新:.NET 5 中有一些改进。现在更容易实施和使用 IDesignTimeDbContextFactory but most importantly Microsoft fixed this bug。现在可以将 SQL 连接字符串作为 args
传递。因此,如果您实现了 IDesignTimeDbContextFactory<T>
,那么将它与 .NET CLI 和 EF 工具一起使用会很简单:
dotnet ef database update --context <DbContextName> --project "**/<ProjectName>.csproj" -- "<SQL connection will be passed into args[0]>"
同样重要的是要强调这仅适用于 .NET 5,并且还需要源代码!您还可以将它与选项 6 一起使用(生成 SQL 脚本) .
第二个烦人的问题一旦实现 IDesignTimeDbContextFactory<T>
这将被所有 ef
命令发现(甚至在开发期间来自 Visual Studio 的命令 运行)。 如果您需要来自 args[0] 的 SQL 连接字符串,您必须在开发期间将其传入 migrations add
或任何其他 ef
命令!
抱歉,列表太长了。但希望它能有所帮助。
在我的上下文中,我从
那里得到了这个 hack
// Hack added so EntityFrameworkCore\Add-Migration initial works
public class ApplicationContextDbFactory : IDesignTimeDbContextFactory<MyContext>
{
MyContext IDesignTimeDbContextFactory<MyContext>.CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("StreamCheckpointContextDB"));
return new MyContext(optionsBuilder.Options);
}
}
我 Program.Main 读起来是这样的...
public static void Main(string[] args)
{
if (args.Contains("JustMigrateMe"))
{
IDesignTimeDbContextFactory<MyContext> factory = new ApplicationContextDbFactory();
var ctx = factory.CreateDbContext(new string[0]);
ctx.Database.Migrate();
ctx.Dispose();
return;
}
// Other stuff
}
}
因此,为了应用迁移,我只需使用添加的参数调用 exe。
对于 EF Core 3.1,我在发布文件文件夹中使用以下行 运行 成功。当然可以使用
调整 MyUser 的路径
dotnet exec --depsfile ProjectName.deps.json --runtimeconfig
ProjectName.runtimeconfig.json
C:\Users\MyUser.nuget\packages\dotnet-ef.1.9\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll
database update --context MyContext --assembly Project.dll --verbose
发布 .Net Core RC1 应用程序后,project.json 中指定的命令已为其创建相应的 .cmd 文件,可以在部署后执行(例如 web.cmd 和 ef.cmd ).在我的例子中,我想在我的部署目标上 运行 以下 Entity Framework 命令:
dotnet ef database update -c MyContext
当我从包含源代码的文件夹中 运行 时,这工作正常,但是在发布之后,它似乎没有在编译的 DLL 中找到命令。我对 RC2 命令变化的理解是 'tools' 可以编译为名为 dotnet-*.dll 的独立应用程序,并且可以通过 CLI 执行。 Entity Framework 核心工具如何在发布的输出中作为可执行 DLL 公开?
仅供参考,我的 build/deployment 工作流程如下:
TeamCity
dotnet restore => dotnet build => dotnet test => dotnet publish
章鱼部署
上传包 => EF 更新数据库 => 等
我在一个项目中遇到了同样的问题,但出于多种原因,我不希望在应用程序启动时自动迁移到 运行。
为了解决这个问题,我更新了 Program.cs
以接受两个参数(下面列出了完整代码)
--ef-migrate
,应用所有挂起的迁移,并且--ef-migrate-check
,以验证是否已应用所有迁移
如果存在参数,则应用 EF 操作并退出程序,否则启动 Web 应用程序。
请注意,它依赖于 Microsoft.Extensions.CommandLineUtils
包来简化命令行解析。
对于章鱼部署,然后可以将包发布两次到不同的位置 - 一次用于 运行ning 迁移,另一次用于虚拟主机。在我们的例子中,我们添加了一个“post 部署 powershell 脚本”,内容为
$env:ASPNETCORE_ENVIRONMENT="#{Octopus.Environment.Name}"
dotnet example-app.dll --ef-migrate
在 docker 上下文中 它也可以完美工作
docker run -it "example-app-container" dotnet example-app.dll --ef-migrate
完全 Program.cs 不包括命名空间和使用:
//Remember to run: dotnet add package Microsoft.Extensions.CommandLineUtils
public class Program
{
public static void Main(string[] args)
{
var commandLineApplication = new CommandLineApplication(false);
var doMigrate = commandLineApplication.Option(
"--ef-migrate",
"Apply entity framework migrations and exit",
CommandOptionType.NoValue);
var verifyMigrate = commandLineApplication.Option(
"--ef-migrate-check",
"Check the status of entity framework migrations",
CommandOptionType.NoValue);
commandLineApplication.HelpOption("-? | -h | --help");
commandLineApplication.OnExecute(() =>
{
ExecuteApp(args, doMigrate, verifyMigrate);
return 0;
});
commandLineApplication.Execute(args);
}
private static void ExecuteApp(string[] args, CommandOption doMigrate, CommandOption verifyMigrate)
{
Console.WriteLine("Loading web host");
//
// Please note that this webHostBuilder below is from an older
// dotnet core version. Newer dotnet cores have a simplified version
// Use that instead and just take the command line parsing stuff with you
var webHost = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
if (verifyMigrate.HasValue() && doMigrate.HasValue())
{
Console.WriteLine("ef-migrate and ef-migrate-check are mutually exclusive, select one, and try again");
Environment.Exit(2);
}
if (verifyMigrate.HasValue())
{
Console.WriteLine("Validating status of Entity Framework migrations");
using (var serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DatabaseContext>())
{
var pendingMigrations = context.Database.GetPendingMigrations();
var migrations = pendingMigrations as IList<string> ?? pendingMigrations.ToList();
if (!migrations.Any())
{
Console.WriteLine("No pending migratons");
Environment.Exit(0);
}
Console.WriteLine("Pending migratons {0}", migrations.Count());
foreach (var migration in migrations)
{
Console.WriteLine($"\t{migration}");
}
Environment.Exit(3);
}
}
}
if (doMigrate.HasValue())
{
Console.WriteLine("Applyting Entity Framework migrations");
using (var serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DatabaseContext>())
{
context.Database.Migrate();
Console.WriteLine("All done, closing app");
Environment.Exit(0);
}
}
}
// no flags provided, so just run the webhost
webHost.Run();
}
}
有一个非常有用的 post 解决了这个问题 here。
它对我有用(我不得不稍微调整一下命令,但它为我提供了良好的入门基础)。
总之:您可以通过传递 ef.dll
来复制 dotnet ef database update
命令(例如,直接从您的 nuget 文件夹(或者如果您没有 nuget,则从其他地方复制,因为您在一台生产机器..)),你的 .dll 包含带有一些附加参数(见下文)到 dotnet.exe
(或 linux 等价物)的迁移。
为完整起见,这里是 .cmd(也来自博客post!)
set EfMigrationsNamespace=%1
set EfMigrationsDllName=%1.dll
set EfMigrationsDllDepsJson=%1.deps.json
set DllDir=%cd%
set PathToNuGetPackages=%USERPROFILE%\.nuget\packages
set PathToEfDll=%PathToNuGetPackages%\microsoft.entityframeworkcore.tools.dotnet.0.0\tools\netcoreapp1.0\ef.dll
dotnet exec --depsfile .\%EfMigrationsDllDepsJson% --additionalprobingpath %PathToNuGetPackages% %PathToEfDll% database update --assembly .\%EfMigrationsDllName% --startup-assembly .\%EfMigrationsDllName% --project-dir . --content-root %DllDir% --data-dir %DllDir% --verbose --root-namespace %EfMigrationsNamespace%
(一个bash版本如果这个cmd在博客里post)
顺便说一句。许多 github 问题中也提到了这种方法:https://github.com/aspnet/EntityFramework.Docs/issues/328 https://github.com/aspnet/EntityFramework.Docs/issues/180
ps:我在 blog of Ben Day 中找到了这个,所以所有功劳归于 Ben!
不幸的是,EF Core 迁移很糟糕,很多... 我已经看到了很多解决方案,但让我们列一个清单。因此,这里是您可以对 运行 执行的操作,并在没有 Visual Studio 的情况下部署 EF 迁移。下面的None是完美的解决方案都有一些注意事项:
- 使用 EF Core Tools here 是一个 link 官方 MS 站点,其中解释了如何安装和使用它。
- 优点:微软官方工具。所有版本的 .NET Core 都支持。
- 缺点:好像是EF6“Migrate.exe”的继承者。 但事实并非如此!目前,如果没有实际的源代码 (.csproj),则无法使用此工具。这不太适合 Live/Prod 部署。通常您的数据库服务器上没有 C# 项目。
- dotnet exec 我试图理解大量记录不完整的参数。并且未能 运行 迁移,直到找到 this script。这个名字暗示了 .NET 核心 2.1,但我已经将它与 3.0 一起使用并且工作了。 更新:没有 运行 它与 .NET 5
- 优点:可以像EF6“migrate.exe”一样使用。最后迁移工作没有源代码。这很可能是从脚本和使用程序集进行迁移的唯一方法。
- 缺点: 设置脚本非常困难,容易遗漏一个参数。没有真正记录解决方案,可能会将 .NET Core 版本更改为版本。此外,您很可能还需要更改代码。您必须实现
IDesignTimeDbContextFactory<DbContext>
接口才能使其工作。还要确保您的部署服务器上有 EF.dll 和 Microsoft.EntityFrameworkCore.Design.dll。 linked 脚本正在许多文件夹中寻找那些。最好是在构建期间将其从您的 .nuget 文件夹复制到您的工件。听起来很复杂,是的......但是 linked 脚本很有帮助。
- 将 EF 迁移添加到您的 Startup.cs 或代码开始 运行ning 并有权访问 DBContext 的任何位置。使用
dbContext.Database.Migrate();
- 优点:迁移每次都会自动发生,无需执行任何其他操作。
- 缺点:迁移每次都会自动发生...您可能不希望发生的问题。 它还会在每次应用程序启动时 运行。所以你的启动时间会很糟糕。
- Custom app. 与前面的解决方案(第3点)类似。因此,您使用 .NET 代码来 运行 迁移。但与其将其放入您的应用程序,不如创建一个小型控制台应用程序 并在其中调用 migrate。您必须构建此应用程序并在部署期间将其放入工件 运行。
- 优点:不涉及脚本。您可以随时在部署管道中调用它。所以你真正的应用程序启动时间不会受到影响。
- 缺点:您必须维护、构建和打包应用程序才能执行 EF Core 迁移。
- 如果您使用 Azure Devops 进行部署,则可以使用 extension like this。或者只搜索 Azure Devops Marketplace。
- 优点:它应该可以工作 :) 没有尝试过它们中的任何一个,也不知道它们的作用。 (我很确定他们也在使用 'dotnet exec' 第 2 点。)
- 缺点:并非每个人都可以从 Azure Devops 访问 Live/Prod。
- 生成SQL脚本:如果none以上的工作你可以生成迁移SQL和运行它之后。 运行 带有“脚本”参数的 EF 工具:
dotnet ef migrations script --output <pathAndFile>.sql --context <DbContextName> --idempotent
。输出是一个 SQL 文件,可以手动执行或通过 CI/CD 管道中的脚本执行。
- 优点:如果您没有访问或模式更改权限来生产仅生产数据库的 DBA,那么这是一个完美的解决方案。您可以向 DBA 提供“安全可靠”的 SQL 文件 运行...
- 缺点:强调此解决方案非常重要必须运行在您的
.csproj
文件所在的工作目录中。所以它需要源代码! 此外,您还必须稍微更改一下代码。需要执行IDesignTimeDbContextFactory<DbContext>
.
更新:.NET 5 中有一些改进。现在更容易实施和使用 IDesignTimeDbContextFactory but most importantly Microsoft fixed this bug。现在可以将 SQL 连接字符串作为 args
传递。因此,如果您实现了 IDesignTimeDbContextFactory<T>
,那么将它与 .NET CLI 和 EF 工具一起使用会很简单:
dotnet ef database update --context <DbContextName> --project "**/<ProjectName>.csproj" -- "<SQL connection will be passed into args[0]>"
同样重要的是要强调这仅适用于 .NET 5,并且还需要源代码!您还可以将它与选项 6 一起使用(生成 SQL 脚本) .
第二个烦人的问题一旦实现 IDesignTimeDbContextFactory<T>
这将被所有 ef
命令发现(甚至在开发期间来自 Visual Studio 的命令 运行)。 如果您需要来自 args[0] 的 SQL 连接字符串,您必须在开发期间将其传入 migrations add
或任何其他 ef
命令!
抱歉,列表太长了。但希望它能有所帮助。
在我的上下文中,我从
// Hack added so EntityFrameworkCore\Add-Migration initial works
public class ApplicationContextDbFactory : IDesignTimeDbContextFactory<MyContext>
{
MyContext IDesignTimeDbContextFactory<MyContext>.CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("StreamCheckpointContextDB"));
return new MyContext(optionsBuilder.Options);
}
}
我 Program.Main 读起来是这样的...
public static void Main(string[] args)
{
if (args.Contains("JustMigrateMe"))
{
IDesignTimeDbContextFactory<MyContext> factory = new ApplicationContextDbFactory();
var ctx = factory.CreateDbContext(new string[0]);
ctx.Database.Migrate();
ctx.Dispose();
return;
}
// Other stuff
}
}
因此,为了应用迁移,我只需使用添加的参数调用 exe。
对于 EF Core 3.1,我在发布文件文件夹中使用以下行 运行 成功。当然可以使用
调整 MyUser 的路径dotnet exec --depsfile ProjectName.deps.json --runtimeconfig ProjectName.runtimeconfig.json C:\Users\MyUser.nuget\packages\dotnet-ef.1.9\tools\netcoreapp3.1\any\tools\netcoreapp2.0\any\ef.dll database update --context MyContext --assembly Project.dll --verbose