EF6 - Run the seedless database update command

I am using Entity Framework 6 and I am using migrations. I have already created the database using the initial migration. Now I have made changes to the Model, and the context has changed, and I want to update the BUT database ... When I try to run the Database-Update command again, the seeds also start, and this leads to errors because some data is inserted again.

So, how can I run the Update-Database command WITHOUT running the seed method?


It's hard to believe that there is no easy option for EF, such as -No-Seed . I am pretty sure what other ORMs do.

+9
source share
7 answers

From the source code of DbMigrationsConfiguration<TContext> :

 /// <summary> /// Runs after upgrading to the latest migration to allow seed data to be updated. /// /// </summary> /// /// <remarks> /// Note that the database may already contain seed data when this method runs. This means that /// implementations of this method must check whether or not seed data is present and/or up-to-date /// and then only make changes if necessary and in a non-destructive way. The /// <see cref="M:System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate``1(System.Data.Entity.IDbSet{``0},``0[])"/> /// can be used to help with this, but for seeding large amounts of data it may be necessary to do less /// granular checks if performance is an issue. /// If the <see cref="T:System.Data.Entity.MigrateDatabaseToLatestVersion`2"/> database /// initializer is being used, then this method will be called each time that the initializer runs. /// If one of the <see cref="T:System.Data.Entity.DropCreateDatabaseAlways`1"/>, <see cref="T:System.Data.Entity.DropCreateDatabaseIfModelChanges`1"/>, /// or <see cref="T:System.Data.Entity.CreateDatabaseIfNotExists`1"/> initializers is being used, then this method will not be /// called and the Seed method defined in the initializer should be used instead. /// /// </remarks> /// <param name="context">Context to be used for updating seed data. </param> 

Basically, you have no option but to implement the add or update logic, because the Seed method will be executed every time after using the initializer.

The AddOrUpdate extension method is useful for this, but I also used this in some cases:

  if (!context.Entities.Any()) { // Seed } 
+10
source

On this page: Database Initializer and Migrations Migration Methods :

The Seed method on the Configuration class is invoked whenever the Update-Database PowerShell command is executed. If you are not using a migration initializer, the Migrations Seed method will not be executed when your application starts.

So, I think that there are not many options here, the Seed migration method will always be called if you run the Update-Database command. I dug if there is a parameter to this command that allows you to specify not to run the Seed method, but I am afraid that it does not exist yet. These are all the options you can use (you can find more information in this link ):

 Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] [-ConnectionStringName <String>] [-AppDomainBaseDirectory <String>] [<CommonParameters>] Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] -ConnectionString <String> -ConnectionProviderName <String> [-AppDomainBaseDirectory <String>] [<CommonParameters>] 

If you are running a sql script to insert data into the Seed method, you can use the booleam condition to avoid re-entering the same fields after the first time.

For additional information, your request has a parameter to avoid executing the Seed method when running the Update-Database command that already exists on this site , which is used by the EF team to collect offers from the community.

+4
source

I moved all of my seed statements to separate methods that can be easily commented before running the "update-database".

 protected override void Seed(Tpsc.EDI.EDIContext context) { try { //EDI.Seed.DoSeed(context); } catch (DbEntityValidationException e) { ... } } 
+1
source

I usually use the update-database -sc , then I run the created script to update the database manually. I did not feel comfortable doing this in the beginning, but now I like to see what happens to my database before it's too late.

+1
source

If you have sql scripts to insert data and want to prevent future insertions, you can use sql merge to avoid duplication. Insert all the data that you have in the temp table with the same structure as your target table, and then use merge to decide when you will insert records or not. If they match, it is because you inserted once.

Suppose S is your temporary table with all your data and T is the summary table

 MERGE Target AS T USING Source AS S ON (T.EmployeeID = S.EmployeeID AND T.EmployeeName LIKE 'S%' AND S.EmployeeName LIKE 'S%' ) WHEN NOT MATCHED BY TARGET THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) WHEN MATCHED THEN UPDATE SET T.EmployeeName = S.EmployeeName WHEN NOT MATCHED BY SOURCE THEN DELETE 

for other links use https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

0
source

Old question, but always helpful. So my contribution is this: use the ConfigurationManager options in your web.config / app.config file .

This is possible because System.Configuration.ConfigurationManager is available from your configuration class.

Do it as follows:

 public sealed class Configuration : DbMigrationsConfiguration<Booking.EntityFramework.BookingDbContext> { public Configuration() { // ... } protected override void Seed(Booking.EntityFramework.BookingDbContext context) { // check configuration if seed must be skipped if (!bool.Parse(ConfigurationManager.AppSettings["Database.Seed"] ?? bool.TrueString)) return; // if here, seed your database // ... } } 

Thus, you can define the application settings in the web.config or app.config file:

 <appSettings> <add key="Database.Seed" value="false" /> <!-- <== do not seed! --> ... </appSettings> 
0
source

I found that if I focus on a specific migration, the Seed method is not called.

 update-database -target migration_name 

Hope this helps someone!

0
source

Source: https://habr.com/ru/post/982800/


All Articles