EF Code First migrations - how to add seed to my migration? - entity-framework

I already have few migrations, and now I am adding another migration, but this time I want to add seed to it. I tried adding this near my Up() and Down() methods:
protected override void Seed(ScykDb context)
{
}
But my compiler says I cannot do that. How can I add seed to my migration?

Seed is not available per migration, only at the DbContext level.
You can easily get around it by adding a call to Sql() in your Up() method:
Sql("insert into ponies (col1, col2.....");

Related

How to use migration programmatically in Entity Framework Core

So I want to use migrations in a programmatic way, for this I've done something like this.
Seed is an extension method which I've created over StoreContext
StoreContext is my DbContext
internal StoreContext(DbContextOptions options)
: base(options)
{
RelationalDatabaseCreator creator = this.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
if (!creator.Exists())
{
creator.Create(); ///=> create database
creator.CreateTables(); ///=> create database tables
}
Database.Migrate(); ///=> apply migrations
if (creator.Exists())
{
this.Seed();
}
}
If the database does not exist the when I ran
Add-Migration Initial
all is good (this is only for my first migration)
If I decide to add new migration
Add-Migration Add_Student_FirstName
a new field in Student then I get this PMC exception
There is already an object named 'SomeTableName' in the database.
the SomeTableName that the console complains about is not necessarily the table on which I've added the change.
But if i go into my code and comment the line for
Database.Migrate(); ///=> apply migrations
and run again
Add-Migration Add_Student_FirstName
all is good again (my migration is added to Migrations folder, but I still have to do the migration by hand using the
Update-Database
command)
So what is wrong in what I'm doing, and how should I fix this so that the migration will be applied automatically when i create it ?
Thanks

Change Entity Framework Migrations table name

I am using Entity Framework 7 and I would like to rename
"__EFMigrationsHistory"
table name to
"__Migrations".
So I have the following on my context:
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
builder
.Entity<HistoryRow>()
.ToTable("__Migrations")
.HasKey(x => x.MigrationId);
// Remaining configuration
}
I am able to create the migration but when I apply it to the database I get:
There is already an object named 'PK_HistoryRow' in the database.
Could not create constraint or index. See previous errors.
I have been trying a few options but I always end with a problem.
Does anyone knows the best way to do this?

Is it safe to modify an entity framework migration so that instead of dropping and recreating an index, it does it a different way?

Azure doesn't support "heap" tables, so I cannot "drop" the main index.
EntityFramework generates a migration that needs to drop and then recreate an index. Is it safe, before running the migration, to modify it so that instead of dropping and recreating the index, it copies the data to a new table with the new index, deletes the old table, then renames the new table to the old table's name?
The final state of the database, in the end, would be the same, so I think it's a safe change to make.
The model snapshot, etc. should all be the same.
We modify migrations regularly to create an additional index or to create a view instead of a table.
public override void Up() {
Sql(#"CREATE VIEW ... ");
}
public override void Down() {
Sql(#"DROP VIEW ... ");
}
As long as the final state of the database is compatible with you model, it is safe. You should only be careful about the "Down" part of the migration. If there is any chance you will ever run it, you should modify not only the Up method but also the Down method in your migration.

Alter Database in Entity Framework 6

I have update my EF to EF 6.0.2 in my code I have the following line of code:
applicationDbContext.Database .ExecuteSqlCommand(#"ALTER DATABASE
CURRENT SET RECOVERY FULL;");
After updating I get the following error message:
ALTER DATABASE statement not allowed within multi-statement
transaction.
I have fixed the problem with a TransctionalBehavior like the the code below:
applicationDbContext.Database.ExecuteSqlCommand(
TransactionalBehavior.DoNotEnsureTransaction, #"ALTER DATABASE CURRENT SET RECOVERY FULL;");
My question:
Why I'm getting this error with EF 6?
My fix is a valid fix for the problem or a devil hiding behind this solution?
Is there any other approach to solve the problem?
Any help will be greatly appreciated!?
EF 6 changes the use of transactions with ExecuteSqlCommand
Starting with Entity Framework 6.0, ExecuteSqlCommand() by default will wrap the command in a transaction if one was not already present. There are overloads of this method that allow you to override this behavior if you wish.
EF 5 did not behave the same way. Your fix is appropriate.
You can now specify a TransactionalBehavior flag to instruct EF on how to handle transactions with this command.
var sqlCommand = String.Format("ALTER DATABASE {0} SET SINGLE_USER
WITH ROLLBACK IMMEDIATE");
db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction,
sqlCommand);
By using the DoNotEnsureTransaction flag, EF will not start a transaction before executing the command. This allows the ALTER DATABASE command to successfully execute.
If you are using Code First approach possible solution is
public partial class AlterDatabase : DbMigration
{
public override void Up()
{
Sql("ALTER DATABASE CURRENT SET RECOVERY FULL", true);
}
public override void Down()
{
}
}

Entity Framework setting FK to nullable

I'm using code first with migrations to build and keep changes to the db in sync.
If there is a class Person that has a property that points to a class FavoriteColor the db schema that gets created is a Person table with a FK called FavoriteColor_Id which is non-nullable.
I need to have that column allow nulls since Person may or may not have a favorite color.
Thx
Ok once again with a good nights sleep I came in to work fresh and was able to tackle this in minutes.
Basically what had happened is that I was expecting that I would change my model class and a nice new migration cs file would be generated for me. There was no change to make to the model class since EF had auto generated this FK for me originally. I then realized that I could still run add-migration from the package manager console and it would create a new file for me where I could add my own code. I also needed to understand the difference between the Up() and Down() method. Sometimes you take these things for granted when everything is auto generated for you.
Here is what solved my issue:
public override void Up()
{
AlterColumn("dbo.Person", "FavoriteColor_Id", c => c.Int(nullable: true));
}