使用DbTool在.NET应用程序中播种数据库(核心)

我们提请您注意DbTool-一个用于将数据库数据导出为各种格式的命令行实用程序,以及Korzh.DbUtils开源库,使用该库可以大大简化.NET(Core)应用程序中数据库的初始“播种”。


使用此工具包,您可以:


  1. 将数据从本地数据库保存到特定文本格式(XML,JSON)的文件中,这些文件易于连接到项目。
  2. 在第一次启动时,使用保存的文件填充应用程序本身的数据库。

下面我将告诉您为什么所有这些都是必要的,如何安装和配置这些工具,并描述使用它们的详细情况。


图片


我们为什么要做DbTool


最初的任务是在.NET(核心)应用程序中创建便捷的数据库填充机制。 由于我们的活动类型 (组件开发)的特殊性,我们经常不得不创建一些小的示例应用程序来演示我们产品的一个或另一个功能。 此类演示项目应与某个测试数据库一起使用,因此建议在应用程序的首次启动时自动创建并填充该数据库。


如果项目使用实体框架(核心)(并且通常发生),那么创建数据库就没有问题。 您只需调用dbContext.Database.EnsureCreateddbContext.Database.Migrate (如果保持迁移很重要)。


但是,随着数据库的填充,一切都变得更加复杂。 首先想到的就是简单地创建带有一串INSERT的SQL脚本,将其放入项目中并在首次启动时执行它。 这行得通(并且我们做了很长时间),但是这种方法存在一些问题。 首先,特定DBMS的SQL语法问题。 通常,原始DBMS与用户实际使用的DBMS不同,并且我们的SQL脚本可能无法正常工作。


第二个可能的问题是数据库本身的迁移。 有时需要稍微更改数据库结构(添加新字段,删除或重命名旧字段,在表之间添加新关系等)。 在这种情况下,在旧结构下创建的SQL脚本通常变得无关紧要,并且其执行会导致错误。 从某些第三方格式加载数据时不会出现问题。 只需跳过新的/更改的字段。 同意出于演示目的,尽管该程序即使在某些新领域中都没有数据启动,也比根本不启动该程序更好。


结果,我们得出以下解决方案:


  1. 演示数据库的“主副本”中的数据以某种“独立”格式(当前为XML或JSON)记录在文件中。 结果文件(或一个存档文件)随项目一起提供。 实际上,此任务与DbTool有关。
  2. 一小段代码插入到我们的程序中,该程序使用Korzh.DbUtils库的类和函数,将第一步中获得的文件中的数据填充到数据库中。
    除上述情况外,DbTool还可简单地用于将数据导出为其他格式并在数据库之间传输数据。 因此,例如,您可以将数据从数据库上传到SQL Server,然后将其加载到MySQL中的类似数据库中

安装方式


DbTool被实现为.NET Core全局工具,即 可以轻松地安装在任何具有.NET SDK 2.1或更高版本的系统上。


要安装该实用程序,您只需要打开控制台(终端/命令提示符)并运行以下命令:


 dotnet tool install -g Korzh.DbTool 

要在安装后进行检查, dbtool在控制台中键入dbtool ,您将看到有关可用命令列表的帮助。



将连接添加到数据库


要开始使用DbTool,您需要添加数据库连接:


 dbtool add {YourConnectionId} {DbType} {YourConnectionString} 

在这里:


  • {YourConnectionId}是您要分配给此连接的标识符,以便以后在运行其他命令时可以访问它。
  • DbType是您的DBMS的类型。 在撰写本文时,DbTool(版本1.1.7)支持SQL Server(mssql)和MySQL(mysql)数据库。
  • 该命令中的最后一个参数是连接字符串。 与您在.NET(核心)项目中已经使用的相同。

一个例子:



之后,您可以通过键入以下命令检查所有连接:


 dbtool connections list 

资料汇出


现在我们已经添加了连接,我们可以使用export命令导出数据库:


 dbtool export {ConnectionId} [--format=xml|json] [--output={path-to-folder}] [--zip={file-name}] 

上面提到的任何选项都可以省略。 如果未指定format则将使用JSON。 如果省略output选项,则结果将以解压格式放置在ConnectionId_yyyy-MM-dd格式的目录中。


例如,以下命令:


 dbtool export MyDb01 --zip=MyDbData.zip 

将在当前目录中创建一个名为MyDbData.zip的ZIP存档,并以JSON格式的数据文件(每个数据库表一个文件)填充它。



资料汇入


您可以将上一步中创建的数据导入回数据库中。 或其他具有相同结构的基地。


重要提示:DbTool不会在导入操作期间创建表。 因此,导入数据的数据库必须已经存在并且具有与原始数据库相同(或至少相似)的结构。

导入命令本身如下:


 dbtool import {ConnectionId} [--input=path-to-file-or-folder] [--format=xml|json] 

--input选项告诉实用程序在哪里查找导入的数据。 如果指定了文件夹路径,则DbTool将在此文件夹中导入.xml或.json文件。 如果这是一个ZIP文件,则该实用程序将首先解压缩该归档文件,然后从中取出必要的数据文件。


与前面的情况一样,--format可以省略,因为DbTool可以通过文件扩展名识别格式。


一个例子:


 dbtool import MyDb01 --input=MyDbData.zip 

图书馆Korzh.DbUtils


DbTool实用程序本身是在开源库Korzh.DbUtils的基础上构建的,该库包含几个实现一些基本数据库操作的软件包。


科尔兹·德布蒂尔斯


定义基本的抽象和接口,例如IDatasetExporter,IDatasetImporter,IDataPacker,IDbBridge


Korzh.DbUtils.Import


包含XML和JSON格式的IDatasetImporter接口的实现。 此外,此程序包还包含DbInitializer类,您可以使用该类来填充项目中的数据(更多信息请参见下文)。


Korzh.DbUtils.Export


包含IDatasetExporter的XML和JSON实现。


Korzh.DbUtils.SqlServer


包含用于MS SQL Server的基本数据库操作(IDbBridge,IDbReader,IDbSeeder)的接口的实现。


柯尔茨·DbUtils·MySQL


包含MySQL数据库接口的实现。


在这里,您可以找到有关Korzh.DbUtils库API完整参考


在应用程序启动时使用Korzh.DbUtils用数据填充数据库


现在,实际上,我们将考虑如何在首次启动应用程序时使用DbTool和Korzh.DbUtils来实现用于填充(填充)数据库的基本脚本。


假设您有一些数据库的“主副本”,您在首次启动应用程序时需要在用户计算机上“复制”该数据库。


步骤1:将主副本导出到JSON


如上所述,只需安装DbTool,向数据库添加连接,然后运行export命令将来自该数据库的所有数据保存到单独的文件夹中:


 dotnet tool install -g Korzh.DbTool dbtool connections add MyMasterDb mssql "{ConnectionString}" dbtool export MyMasterDb 

步骤2:将数据文件添加到我们的项目中


在上一步之后,我们将创建一个新文件夹,格式为MyMasterDb-yyyy-MM-dd,其中包含一堆JSON文件(每个表一个)。 只需将此文件夹的内容复制到我们的.NET(核心)项目的App_Data \ DbSeed中即可。 请注意,对于.NET Framework下的项目,您还需要手动将这些文件添加到项目中。


步骤3:DB初始化代码


尽管该过程本身(详细信息)适用于.NET Core或.NET Framework(版本4.6.1或更高版本)下的任何类型的项目,但是为了简化描述,假设我们正在谈论一个与.NET Core一起使用的ASP.NET Core项目。 SQL Server数据库,并且该数据库是使用Entity Framework Core自动创建的。


因此,要解决从一开始就用数据填充数据库的问题,我们需要:


1.将Korzh.DbUtils库软件包安装到NuGet项目中


在这种情况下,我们需要其中两个:


  • Korzh.DbUtils.Import
  • Korzh.DbUtils.SqlServer

2.添加初始化代码


这是我们应在Startup.Configure方法末尾添加的此类代码示例:


 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { . . . . app.UseMvc(); using (var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope()) using (var context = scope.ServiceProvider.GetService<AppDbContext>()) { if (context.Database.EnsureCreated()) { //run only if database was not created previously Korzh.DbUtils.DbInitializer.Create(options => { options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); //set the connection string for our database options.UseFileFolderPacker(System.IO.Path.Combine(env.ContentRootPath, "App_Data", "SeedData")); //set the folder where to get the seeding data }) .Seed(); } } } 

为了使所有内容都变得漂亮,或者如果您需要在首次启动时执行一些其他初始化(例如,添加多个用户帐户和/或用户角色),最好将所有这些代码安排为接口的单独扩展方法(我们将其EnsureDbInitializedIApplicationBuilder


可以在GitHub的EasyQuery库演示项目中找到这种实现的示例


在这种情况下,您只需要在Startup.Configure方法的末尾添加一个调用即可:


 public void Configure ( IApplicationBuilder,   IHostingEnvironment) { . . . . app.UseMvc (); //Init database (only if necessary) app.EnsureDbInitialized(Configuration, env); } 

未来计划


尽管库和实用程序是在非常特定的情况下编写的,但我们尝试使所有操作都尽可能灵活和可扩展,因此启用其他功能将不是问题。


在可能的改进中,我们看到以下内容:


  • 支持其他数据库(PostgreSQL,Oracle,SQLite,MariaDB)


  • 您可以导出数据的新格式(CSV,Excel,HTML)


  • 将数据从数据库直接复制到数据库的操作(现在您可以通过连续两次调用export / import命令来实现它)


  • 完全备份/还原操作,完全保留数据库结构及其在恢复过程中从头开始的创建。



我们将很高兴听到任何建议或评论,并非常感谢GitHub库的新星:)


感谢您的关注!

Source: https://habr.com/ru/post/zh-CN466541/


All Articles