Run an EF core migration without a transaction? - entity-framework-core

I've got a Postgres database where I use the Postgres type of Enum. The issue I'm having is that when I add an enum via a migration, I get an error stating that it can't be ran in a transaction. This would mean that if I ever had to recreate a database it would always fail because that migration would never run correctly.
So my question is, is there a way of turning off transactions in entity frameworks migrations? Or if you can, whether you would want to?
For clarity, here's a link to the question I've got about the specific failing migration.
ALTER TYPE ... ADD cannot run inside a transaction block - Entity Framework
Thanks

I found that there's an overload for the .Sql command where you can specify true to suppress a transaction.
migrationBuilder.Sql("your sql statement", true);

Related

entity framework core migration

I'm new to Ef core. Using migrations. I made some changes in my code recently.
Got following error:
The operation failed because an index or statistics with name 'IX_JobPosts_Role_Domain1_Filters_Item1_ExperienceLevelId' already exists on table 'JobPosts'.
Ok, so I did what I usually do when I encounter errors, delete my database and previous migrations and start all over again.
First migration works fine everytime. Second migration prompts the same error even though no changes has been made to my code.
Why does it keep adding columns that already exists?
the reason is that ef core does not support nested owned types.

EF6 hybrid CreateDatabaseIfNotExists and MigrateDatabaseToLatestVersion approach

We want to support all of the following scenarios using a EF6 database initializer to create or update an existing database from our EF6 model:
Create and initialize a new database.
Update an existing (legacy) database that has no __MigrationHistory table yet.
Update an existing (migrated) database that already has a __MigrationHistory table.
When using the CreateDatabaseIfNotExists database initializer, it covers only the first scenario. But then we cannot further evolve our data model.
When using the MigrateDatabaseToLatestVersion database initializer with an InitialDatabase migration that creates the base line database, we can support scenario 1 and 3. But it fails to upgrade existing legacy databases because the generated SQL statements are not idempotent. They fail e. g. with a "Table 'xy' already exists" error.
When using the MigrateDatabaseToLatestVersion database initializer with an empty InitialDatabase migration (=empty Up() method body), then we can only support scenario 2 and 3, but we cannot create new database from scratch.
I am looking for a way that combines the best of both worlds and supports all three required scenarios. Unfortunately this seems impossible with the current EF6 design. The problem I am facing is that the DbMigration steps are discovered using reflection and there seems to be no (clean) way to intercept this. What I would like to do is to write an enhanced "hybrid" database initializer that:
1. Checks if the database exists.
2. If not, then execute all migrations (=default behavior of MigrateDatabaseToLatestVersion).
3. Otherwise check if it is already enabled for migrations (i. e. table __MigrationHistory exists).
4. If yes, then execute only the pending migrations (=default behavior of MigrateDatabaseToLatestVersion).
5. Otherwise execute all DbMigrations except the very first "InitialDatabase" migration. This should also create the __MigrationHistory table and include all(!) migrations (including the very first "InitialDatabase" migration).
I don't find a way to implement step 5.
I would be happy with a "hack" that lets me just catch and ignore exceptions from upgrade operations of the first step (with a well-known MigrationId). I already thought about deriving a class from DbMigrator and override the ApplyMigration method with a
try
{
base.ApplyMigration(...)
}
catch
{
...ignore if migrationMetadata.Id=="my well-known id"..
}
block. But this is impossible because the ApplyMigration is internal.
Any ideas on this?

EF Core Why Do Migrations need names?

What is the point in given migrations names?
dotnet ef migrations add {MigrationName}
The file that it generates seems to start with the timestamp the migration was create, so whats the value of the name?
For the same reason source control usually requires commit messages--to help developers differentiate between them.
The dotnet ef migrations add command is always going to require a name, but you could override the internal IMigrationsIdGenerator to ignore it and just use the timestamp.
But since you have to specify them anyway, you might as well just use a sequence like M1, M2... if you don't feel they're important.
because that name gets store for possible rollback.
Also, with the command posted it has NOTHING to do with entityframework below 6.3
reference table _EntityMigration in your database...

using EF migrations with SQL Server (Not express/localdb)

New to EF.
Am using code first but created from an initial database.
First issue is when I added a foreign key to the model After executing add-migrations from the console it created migrations to create the entire tables rather than just adding the foreign keys to the existing tables using AddForeignKey(....),
And when I try to update-database it tries to create a localdb database under and i get the error
Directory lookup for the file "C:\src\Project\App_Data\TheDatabase.mdf" failed with the operating system error 2(The system cannot find the file specified.).
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
Which kind of makes sense because i'm not using sqlexpress.
It seems as though I need some configuration to coax it into action.
Any useful advice would be welcome.
I found a solution although maybe this is more of a workaround
I did change the connection factory but it did nothing. Still tries to use App_Data folder and looks for an MDF there.
I found a work around though. The package manager lets you override the connection string so i just did that and it works fine.
As for the other part of my question regarding why it was trying to create the tables. What I needed to do first it use the Add-Migration with -IgnoreChanges and update-database will then store an initial blank migration so from then on, any changes you make will be just those incremental ones I was referring to.
Here was the link for that. https://msdn.microsoft.com/en-us/data/dn579398.aspx?f=255&MSPPError=-2147217396
Thanks to those who offered help.
Hope this helps. Basically, EF needs your first snapshot of your database to create the model classes as the initial state, after that you can add migrations.
If it doesn't help, can you post your connection string and number of migrations your have?

Entity Framework 5 Code Migrations

Where is stored information about current database state (what migration is applied)? I suppose it can be "dbo.__MigrationHistory" table or this table is just for logging purpose?
If I enabled migration, added migration and updated my database. After that I checked-in code to SVN and another developer checked it out. What this another developer has to do to create/update his own database?
I see such options:
1) Call Update-Database command right away.
2) Do everything from beginning (Enable-Migration, Add-Migration, Update-Database).
3) Do everything but skip Add-Migration step (it is already present and it seems strange to add it once again for every new developer).
Which of my assumption is right or if no one where is the right way?
To retrieve which migrations have been applied to the database, you can use the Get-Migrations command (reference).
Everything depends on how the database is created, which initializer you are using.
This article is worth reading if you are unfamiliar with those.
When using the DropCreateDatabaseAlways initializer, you don't really need to care about updating your database, because your database will be deleted & recreated at each application startup.
When using the DropCreateDatabaseWhenModelChanges initiliazer, your database will be dropped then recreated if EF detects the model has changed at the application startup.
When using the CreateDatabaseIfNotExists initilizer or if no initializer has been defined, your database will be created if it does not already exists. If the database already exists & you added a Migration, you (and every developer retrieving your code) need to use the Update-Database command to update the database.
There is a new initializer introduced with Code-First Migrations: MigrateDatabaseToLatestVersion, this initializer automatically update the database to the latest Migration defined.
See this page's last section: http://msdn.microsoft.com/en-us/data/jj591621.