Manually run the Seite () method of Entity Framework migration, including after the Down () transfer

Is there an easy way to manually run the Entity Framework migration Seed () method from the package manager console, including after Down () migration ( Update-Database -TargetMigration foo )? The answer to " The first method to migrate the migration code" without migration "describes how to manually run the Seed () method, which should call Update-Database , but it doesn Work when the database is on an older migration and should not be updated. The same question was asked in How to run the Seed () method of the migration configuration class ", but it was asked as part of a multi-part question, and this part remains unanswered (although the whole question is marked as answered now).

I ask because I have a cleanup code that needs to be run after the migration has been applied. A call from Seed () is great for Up () migration. However, I don't know how easy it is to call it for Down () migration. I need a simple one or two liners that will work from the package manager. I know that I can call the C # method after calling [Reflection.Assembly] :: LoadFile () for all the necessary DLLs, but there are enough dependencies that this would be cumbersome and error prone.

I know that Seed () is not an ideal place for Down () migration cleanup code (to add some context based on DrewJordan's answer), but using Down () is unfortunately not viable for several reasons. From a practical point of view, this is not viable because the cleanup must convert several gigabyte data, and this caused SQL Server Express to crash when I tried a simple copy in Down (), probably because the resulting transaction size was huge. Secondly, even from a hypothetical point of view, I do not believe that there is a way to convert the data to the extent necessary in Down (), because the current SQL lines cannot be read in C # as part of the transaction and the data conversion must take place in C #. For more on this limitation, see my other question: Converting data using C # during migration of the Entity Framework . "Some design trade-off was needed to make cleanup work, and I used Seed () as this trade-off. Cleanup code does not need to be run from Seed () as such, but I donโ€™t know what else can be called from the package manager without changing the current migration.

There is another scenario where it would be useful to call Seed () or another cleanup code yourself without changing the current migration. Consider the scenario in which an error occurred in the Seed () / cleanup method. You are fixing the error and want to restart it without changing the current migration. Putting the cleanup logic in Down () will not solve the problem, because Down () will not be called when the database is already in this migration.

+5
source share
2 answers

I understand that you asked to run it from the PM console: AFAIK this is not possible. This use case is not suitable for Seed : I would recommend if you have any changes made to the Down method, either write the SQL scripts to run, or create a context in Down and do whatever it is.

This is a bad idea because Seed expects to update the latest migration. This will allow you, for example, to write statements that cannot be successful in a previous version of your context, for example, when a column is added to the model but is not yet applied to the database. I have not tried this, but at least throw an exception and may not be able to write any changes.

If you really think this is a good idea, you can add a method to your configuration:

 public void CallSeed() { using (var c = new Context()) // create your context { Seed(c); } } 

And call it from "Down":

 var c = new Configuration(); c.CallSeed(); 
+1
source

I found the basis for something similar that this would work. Itโ€™s a hack, but Iโ€™ll post it here because I know that others wanted something like that, judging by the other issues Iโ€™m involved with.

The idea is to link another migration command that can be run from the package manager and which will not change the database itself - I will use Get-Migrations . This will allow the package manager team to do the hard work of finding the right configurations, loading the right assemblies, etc. I will contact this command by invoking my cleanup code from the constructor of my subclass DbMigrationsConfiguration. I only want to run the cleanup code intentionally, and not every time the configuration is configured, so I will also check the sentinel environment variable before running the cleanup code. Later, I plan to move the cleanup code from Seed () to separate it from the actual seeding, but as others have asked to manually run Seed () in the past, I will use this as an example here.

I changed my subclass of DbMigrationsConfiguration as follows:

 internal sealed class Configuration : DbMigrationsConfiguration<TimsDB> { public Configuration() { if ("true".Equals(Environment.GetEnvironmentVariable("RUN_SEED"))) using (TimsDB db = new TimsDB()) { Database.SetInitializer<TimsDB>(null); Seed(db); } } } ... } 

This can then be used to manually call the Seed () method from the package manager:

 PM> $Env:RUN_SEED = "true" PM> Get-Migrations PM> $Env:RUN_SEED = "false" 
0
source

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


All Articles