当前位置: 首页 > 编程语言 > C#

如何创建初始化器来创建和迁移mysql数据库?分享

时间:2023-04-11 12:06:15 C#

如何创建初始化器来创建和迁移mysql数据库?我学习如何使用EF已有一周左右的时间,但我一直遇到创建/更新数据库的问题。如果数据库不存在,我可以创建一个初始化程序来创建数据库:staticclassProgram{staticvoidMain(){Database.SetInitializer(newGumpDatabaseInitializer());....classGumpDatabaseInitializer:CreateDatabaseIfNotExists{publicGumpDatabaseInitializer(){}protectedoverridevoidSeed(GumpDatabasecontext){context.Database.ExecuteSqlCommand("CREATEUNIQUEINDEXNameONStations(Name)");//其他东西}}或者我可以创建配置来迁移数据库staticclassProgram{staticvoidMain(){Database.SetInitializer(newMigrateDatabaseToLatestVersion());....内部密封类Configuration:DbMigrationsConfiguration{publicConfiguration(){AutomaticMigrationsEnabled=true;SetSqlGenerator("MySql.Data.MySqlClient",newMySql.Data.Entity.MySqlMigator());}protectedoverridevoidSeed(GumpDatabasecontext){}每个都工作正常,但我还没有想出一种方法来做到这两个。我可以通过更改SetInitializer调用在两个初始值设定项之间切换,但是如果我想创建数据库(如果它不存在)并且迁移它(如果存在)怎么办?我需要创建自定义初始化器吗?谢谢根据NSGaga答案编辑publicCreateOrMigrateDatabaseInitializer(){_configuration=newTConfiguration();}publicCreateOrMigrateDatabaseInitializer(stringconnection){Contract.Requires(!string.IsNullOrEmpty(connection),"connection");_configuration=newTConfiguration{TargetDatabase=newDbConnectionInfo(connection)};}voidIDatabaseInitializer.InitializeDatabase(TContextcontext){Contract.Requires(context!=null,"context");如果(context.Database.Exists()){如果(!context.Database.CompatibleWithModel(throwIfNoMetadata:false)){varmigrator=newDbMigrator(_configuration);迁移器.Update();}}其他{上下文。数据库.创建();种子(上下文);context.SaveChanges();}}protectedvirtualvoidSeed(TContextcontext){}}和内部密封类Configuration:DbMigrationsConfiguration{publicConfiguration(){AutomaticMigrationsEnabled=true;AutomaticMigrationDataLossAllowed=false;SetSqlGenerator("MySql.Data.MySqlClient",newMySql.Data.Entity.MySqlMigrationSqlGenerator());}protectedoverridevoidSeed(GumpDatabasecontext){}}和classGumpDatabaseInitializer:CreateOrMigrateDatabaseInitializer{publicGumpDatabaseInitializer(){}protectedoverridevoidSeed(GumpDatabasecontext){context.Database.ExecuteSqlCommand("CREATEUNIQUEINDEXNameONStations(Name)");context.Database.ExecuteSqlCommand("CREATEUNIQUEINDEXNameONSequences(Name)");context.Database.ExecuteSqlCommand("在StationPartNumbers(StationId,PartNumberId)上创建唯一索引StationPartNumber");}}最后staticvoidMain(){Database.SetInitializer(newGumpData基础初始化器());我想你快到了——你可以查看MigrateDatabaseToLatestVersion的源代码(它是开源的http://entityframework.codeplex.com/)——它非常简单,它所做的就是调用DbMigrator——这就是我所能做的看到您需要做的所有事情似乎是将两者合并-使用一个或另一个作为基础,在那里添加其他功能-我认为这应该可以正常工作。类CreateAndMigrateDatabaseInitializer:CreateDatabaseIfNotExists,IDatabaseInitializer其中TContext:DbContext其中TConfiguration:DbMigrationsConfiguration,new(){privatereadonlyDbMigrationsConfiguration_configuration;publicCreateAndMigrateDatabaseInitializer(){_configuration=newTConfiguration();}publicCreateAndMigrateDatabaseInitializer(stringconnection){Contract.Requires(!string.IsNullOrEmpty(connection),"connection");_configuration=newTConfiguration{TargetDatabase=newDbConnectionInfo(connection)};}voidIDatabaseInitializer.InitializeDatabase(TContextcontext){Contract.Requires(context!=null,"context");varmigrator=newDbMigrator(_configuration);迁移器.Update();//继续“种子”的“CreateDatabaseIfNotExists”base.InitializeDatabase(context);}protectedoverridevoidSeed(TContextcontext){}}像这样称呼它……Database.SetInitializer(newCreateAndMigrateDatabaseInit初始化器());...实际上,像您对CreateDatabaseIfNotExists所做的那样覆盖它(因为它是通用实现)(您只需要配置额外的“参数”)-并且只需提供“种子”类GumpDatabaseInitializer:CreateAndMigrateDatabaseInitializer{protectedoverridevoidSeed(GumpDatabasecontext){context.Database.ExecuteSqlCommand("CREATEUNIQUEINDEXNameONStations(Name)");}}...并将其命名为Database.SetInitializer(newGumpDatabaseInitializer());编辑:根据评论——DbMigrator不应运行两次。它总是检查(需要一点时间)并进行“空白”更新并继续前进。但是如果你想在进入之前删除它并“检查”-这应该有效(更改上面的类似部分)......varmigrator=newDbMigrator(_configuration);如果(!context.Database.CompatibleWithModel(throwIfNoMetadata:false))如果(migrator.GetPendingMigrations().Any())migrator.Update();(这是一个冗余/双重检查-其中一个if-s应该足够了。在那里休息-看看发生了什么,它不应该进来-一旦Db被迁移。正如我提到的,它对我来说很好测试出来。编辑:替换InitializeDatabase的内部vardosed=!context.Database.Exists();//&&newDatabaseTableChecker().AnyModelTableExists(context);//检查是否播种-我们“缺少”'AnyModelTableExists'-如果需要,可以复制/完成...varmigrator=newDbMigrator(_configuration);//if(doseed||!context.Database.CompatibleWithModel(throwIfNoMetadata:false))if(migrator.GetPendingMigrations().Any())migrator.Update();//继续“种子”的“CreateDatabaseIfNotExists”base.InitializeDatabase(context);如果(种子){种子(上下文);context.SaveChanges();}如果migratefirst,它解决了(中途)非播种问题。迁移必须是第一位的,否则你会遇到问题。你仍然需要做对-如果不是你可能需要,这就是要点-但如果MySQL等有任何问题,可能会有一些腿部工作。注意:如果你有一个数据库,仍然没有调用种子,但它是空的。问题是混合两个不同的初始值设定项。所以你必须解决这个问题-通过实现内部Create...(我们不能调用的那个)或其他东西。实际上应该是:varmigrator=newDbMigrator(_configuration);如果(!context.Database.CompatibleWithModel(false)||migrator.GetPendingMigrations().Any())migrator.Update();因为如果我们有一个与我们的数据库模型无关的迁移,例如在我们的任何表中插入一行,就不要执行迁移。要同时执行这两项操作(种子和迁移),您实际上只需要使用MigrateDatabaseToLatestVersion初始值设定项进行迁移。当为上下文启用迁移时,将创建一个派生自DbMigrationsConfiguration的Configuration类,您可以重写DbMigrationsConfiguration数据库的Seed方法来为其设定种子。请注意,执行此方法时数据库可能已经包含种子数据,但AddOrUpdate扩展方法可以方便地帮助您在数据库中执行“更新插入”。这与某些其他数据库初始化程序的Seed方法不同,其中数据库仅在最初创建时播种。但是,在使用迁移时,您可能希望在数据库更改时更改种子数据,使用MigrateDatabaseToLatestVersion可以做到这一点。要将种子组合与迁移相结合,您必须在新项目中执行以下步骤:创建代码优先的DbContext以及关联的实体在包管理器控制台中,执行命令Enable-Migrations在Migrations文件夹中,使用Seed方法生成一种配置。您可以修改此方法来为数据库设置种子:protectedoverridevoidSeed(MyContextcontext){//添加名称为“Foo”和“Bar”的两个实体。context.MyEntities.AddOrUpdate(e=>e.Name,newMyEntity{Name="Foo"},newMyEntity{Name="Bar"});您需要创建一个派生自MigrateDatabaseToLatestVersion的数据库以初始化MigrateDatabaseToLatestVersion:classMyContextInitializer:MigrateDatabaseToLatestVersion{}您还必须在应用程序启动时传递对数据库的调用。SetInitializer(newMyContextInitializer())或使用该元素在App.config文件中配置初始化程序。在生成的Configuration类的构造函数中,您可以启用自动迁移:publicConfiguration(){AutomaticMigrationsEnabled=true}但是,在团队中,您可能不想这样做。在这种情况下,您将必须创建初始迁移(除非它是在您执行Enable-Migrations时创建的)。在包管理器中,执行命令Add-MigrationInitialCreate。这将创建创建数据库所需的第一个迁移。此时,您有一个带有迁移的DbContext和一个Seed方法。总结一下:启用迁移,使用MigrateDatabaseToLatestVersion初始值设定项,并在启用迁移时生成的Configuration类中添加种子数据。虽然MigrateDatabaseToLatestVersion实际上会创建数据库(如果它不存在),甚至允许您为其播种,但如果您已经有一个基于CreateDatabaseIfNotExists的有效解决方案和/或不想通过测试种子数据的存在使其复杂化,那么您可以只使用以下方法继承而不是CreateDatabaseIfNotExists:publicclassCreateOrMigrateDatabaseInitializer:CreateDatabaseIfNotExists,IDatabaseInitializerwhereTContext:DbContextwhereTConfiguration:DbMigrationsConfiguration,new(){voidIDatabaseInitializerEx.text.InitializeDatabase(TContext)){if(!context.Database.CompatibleWithModel(throwIfNoMetadata:false)){varmigrationInitializer=newMigrateDatabaseToLatestVersion(true);migrationInitializer.InitializeDatabase(context);}}base.InitializeDatabase(上下文);这是基于以前的答案和OP自己的解决方案。这也适用于其他提供商,但我只测试了SQLServer。以上就是C#学习教程:如何创建初始化程序来创建和迁移mysql数据库?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: