I have an ASP.NET MVC project using EF code first and migrations.
I am trying to add a new property to a class. For that I create the migration code in order to add the specific column in the table related to that class.
My migration code is the following:
public partial class Add_DataRequisicao_to_BiblRequisicao : DbMigration
{
public override void Up()
{
AddColumn("dbo.BiblRequisicoes", "DataRequisicao", c => c.String(nullable: false, defaultValue: "01/01/1900 00:00"));
}
public override void Down()
{
DropColumn("dbo.BiblRequisicoes", "DataRequisicao");
}
}
And the property to add to the class is the following:
[Required]
[Display(Name = "Data Requisição")]
public string DataRequisicao { get; set; }
When I publish the project and go to the project web site, I get the following error message:
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
Inspecting the database, I see that the migration was run with success because the column was created. In the migration table, there also is a new entry that indicates that the migration ran.
The migration entry:
MigrationId: 201704261436437_Add_DataRequisicao_to_BiblRequisicao
ContextKey: WebAppInvestigacaoMultimedia.Migrations.Configuration
Model: 0x1F8B0800000...
ProductVersion: 6.1.3-40302
I don't understand why I get the error message if the migration ran with success and the name and the type of the property is the same as the add column of the table.
This error is usually linked to changes to the model that haven't been added to a migration script yet.
If you look at the folder where you have your migrations, you should have resx files, those files contain a "snapshot" of the model at the time the migration was generated. It therefore knows if there are changes that have been made to the model and will not let you do an Update-Database if there are pending changes.
To resolve the issue, you either have to rollback any changes you made to the model since the last migration you made, or create a new migration using Add-Migration and then do Update-Database.
If you're working with a team, those issues happen sometimes if both you and others have made changes to the model or created migrations. Check this interesting MSDN article to get a few insights on how leverage those issues.
Related
I have my project that is a Xamarin.Forms app, with a Azure SQL Database and an Azure Mobile App Service.
I am using code-first to create the database.
Now I want to rename a class "Customer" to "Company".
The migration is done correctly, the existing table is renamed.
However, there is a trigger, created automatically, that is renamed as well, but the table name that is uses is not modified. So the triggers doesn't work anymore.
I suppose the trigger exists because of the "ServiceTableColumn" convention added to the modelbuilder.
This is the generated migration code:
public partial class rename_customer_to_company_step_1 : DbMigration
{
public override void Up()
{
RenameTable(name: "dbo.Customers", newName: "Companies");
}
public override void Down()
{
RenameTable(name: "dbo.Companies", newName: "Customers");
}
}
This is the script for the trigger (after executing the above migration):
CREATE TRIGGER [dbo].[TR_dbo_Customers_InsertUpdateDelete]
ON [dbo].[Companies]
AFTER INSERT, UPDATE, DELETE AS
BEGIN
UPDATE [dbo].[Customers]
SET [dbo].[Customers].[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME()) FROM INSERTED
WHERE inserted.[Id] = [dbo].[Customers].[Id]
END
As you can see, the table itself has been renamed (ON [dbo].[Companies]
), but the contents of the triggers still references the previous table name (UPDATE [dbo].[Customers]).
Of course the trigger does not work.
How can I have the trigger modified correctly? Is the trigger really necessary? Can I get rid of these triggers?
Any ideas how to correct this? I prefer not to update the triggers manually, why am I using code-first migrations if I need to do that?
Thanks in advance,
Joris
If the code-first migration didn't do it, you will have to edit the code-first migration file or update the triggers yourself. The triggers are relatively easily done if this is a one-time thing. See chapter 3 of the Zumo Book at http://aka.ms/zumobook for details on this.
I have a entity framework 6 code-first project. I deleted my database and want to re-create it from scratch. When I run update-database some of the migrations do not run. That causes an error later because the database is not in the expected state.
This is the first migration that is skipped:
using System.Data.Entity.Migrations;
public partial class add_ConversationEntry_Type : DbMigration
{
public override void Up()
{
AddColumn("dbo.ConversationEntry", "Type", c => c.String(nullable: false));
}
public override void Down()
{
DropColumn("dbo.ConversationEntry", "Type");
}
}
It looks standard. It inherits from DbMigration and does nothing weird. The next 3 also are skipped and they all affect that dbo.ConversationEntry table.
With update-datebase -verbose it shows 'Applying explicit migrations:' and lists the migrations and these are missing from that list.
I have verified that these are also in the project file.
Where does update-database get the list of migrations?
Why would some be skipped?
The best thing to do in this scenario is to create an idempotent script of all the migrations and see what Entity Framework is trying to do:
update-database –SourceMigration $InitialDatabase -Script
This should have everything needed to create the database, the __MigrationHistory table and to consecutively apply your migrations.
If all other databases you care about are up to date, you could simply reset the migrations. Yet another option would be to switch the initializer to createdatabaseifnotexists which would create a new database based on your model.
Each entity framework migration consists from three files
entity class .cs
and additional code-behind files
metadata file .Designer.cs
database model snapshot .resx
Make sure <timestamp>_dd_ConversationEntry_Type.Designer.cs file is not missing and is included in your project.
easy easy
Make sure the build action is "Compile" and don't forget to mark this answer as "Correct Answer".
enter image description here
I am trying to develop a small application using ASP.NET MVC 5.
I am using Entity Framework with a code first approach.
To get started, I created my first model and then followed the steps below to create the table in the database
I opened the Package Manager Console
I executed Enable-Migrations
I executed Add-Migration InitilizeModel1Table
Finally, to create the table I executed Database-Update
In step 3 created a migration called datetime_InitilizeModel1Table which created the code that will create the table automatically.
In step 4, it applied the create table command and created the table in the database as expected.
Now, I created 3 more models and what I like to do is create a separate migration for each to keep my code separated.
So I thought I would start again at step 2 and so the following
Add-Migration InitilizeModel2Table
Add-Migration InitilizeModel3Table
Add-Migration InitilizeModel4Table
Database-Update
But the command Add-Migration InitilizeModel2Table is creating an empty migration without the code that is needed to create the tables.
Here is an example of one
namespace App.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class InitilizeModel2Table : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
How can I create a new migration for each model without having to manually write the migration script to create the tables?
The problem here was that you weren't adding your models to the context, hence EF did not detect the changes.
EF links the state of the model to the migration via the __MigrationHistory table/the migration files themselves. It compares the latest value in __MigrationHistory to the current state of your context, if they are different then a new, non-empty migration will be created when you run Add-Migration X.
Here are a couple of resources describing code-first migrations.
I am by no means an EF expert, so I may be slightly off in the details here.
I have a web application with local database in production environment. In new build I decided to change database and added database migration.
I ran Enable-Migrations in NuGet console.
Program has generated 201410141412423_InitialCreate.cs file as I already had database - there're some code that initialize my database schema.
Then I added one field in model Workstation
public class Workstation
{
public int Id { get; set; }
[StringLength(15)]
public string Name { get; set; }
public DateTime LastCall { get; set; } //this field was added
public string UserConfiguration { get; set; }
private readonly ICollection<StatusBase> _statuses = new Collection<StatusBase>();
public virtual ICollection<StatusBase> Statuses
{
get { return _statuses; }
}
}
I ran Add-Migration WorkstationLastCallAdded command in NuGet console. New file with migration logic was generated with next code:
public partial class WorkstationLastCallAdded : DbMigration
{
public override void Up()
{
AddColumn("dbo.Workstations", "LastCall", c => c.DateTime(nullable: false));
}
public override void Down()
{
DropColumn("dbo.Workstations", "LastCall");
}
}
I also added next code in Global.asax file to update my database
protected void Application_Start()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDbContext, MigrationConfiguration>());
}
Then I build it and run, and everything works fine.
When I deploy new build to server, there's a database file with some data on the server. The database has old scheme - without LastCall field. So I expect migration updates my database and I won't loose any data.
When I run my site after deploy - everything works fine. Data is not lost and database is updated correctly.
If I restart server or IIS and run my site again - I've got an error.
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
When I open local db and watch _MigrationHistory table - there're two rows with 1410151540264_InitialCreate and 201410141956597_WorkstationLastCallAdded migration id's.
Could anybody help me please? Any ideas what's going wrong? Why it works correctly on first run after update but fails on the second?
Thank you in advance.
IIRC, the answer it pretty simple. You have two migrations:
201410151540264_InitialCreate
201410141956597_WorkstationLastCallAdded
You InitialCreate miration is newer than WorkstationLastCallAdded migration. Why? Because InitialCreate is implicitly added to _MigrationHistory table when your DB is created for the first time and you have no migrations. The timestamp for InitialCreate in this case is, of course, equal to current server time. WorkstationLastCallAdded, on the other hand, has a fixed timestamp which reflects the time when you ran Add-Migration WorkstationLastCallAdded command. Therefore, if you create a database after you've created WorkstationLastCallAdded, InitialCreate will be the 'newest' migration.
What happens next? Db initializer searches for the newest migration and finds InitialCreate. Then it compares InitialCreate model hash with current model hash and sees that these hashes are different (of course they are, you have changed your model!). And then you got your error.
The easiest way to solve this is to rename your WorkstationLastCallAdded timestamp (in migration designer file) to something like this:
99999999999999_0001_WorkstationLastCallAdded
A bunch of nines ensures that this migration is older than InitialCreate. 0001 reflects the order of migration. If you want to create another migration, you should name it like this:
99999999999999_0002_SomeOtherFieldAdded
Hope this helps!
I have an ASP.NET MVC 4 project with Entity Framework 5, .NET 4.5 and Visual Studio 2012.
In my solution I've put all the models in a project called Model, all the Repositories and my DbContext in one more project called Data.
I activate the migrations in the Data project with the Enable-Migrations command. I decide to handle them manually. If I create a new migration with the Add-Migration command everything works very well. If, for example, I add a new column to a table, it works fine. I can see the new column in the database schema and I see the new record into the _MigrationHistory table.
At this point, with the new column created, I need to add this column to the right model. So, i add this method to my code-first model class and I run the project.
It delete my database, and init it with the initial migration.
I can't tweak a model without loosing all data.
How I can avoid this behavior?
Thanks
UPDATE:
Configuration.cs
namespace NegoziazioneEventi.Data.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<NegoziazioneEventi.Data.NeDataContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(NegoziazioneEventi.Data.NeDataContext context)
{
}
}
}
Application_Start() in Global.asax
protected void Application_Start()
{
// init basic data on database
System.Data.Entity.Database.SetInitializer(new Models.InitData());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
_container = Bootstrapper.GetWindsorContainer();
}
I decide to handle them manually. If I create a new migration with the Add-Migration command everything works very well.
...
At this point, with the new column created, I need to add this column to the right model. So, i add this method to my code-first model class and I run the project.
That is completely wrong usage of migrations and it is also the reason why EF deletes your database. You must first add property to model and then add migration because EF needs to store correct data into _MigrationHistory table to match that record with the real meaning of that migration.
With your current approach EF runs the application and checks _MigrationHistory table but the record in the table doesn't contain information about your newly added property so EF believes that new change was done to your model and uses default strategy to delete database and create a new one reflecting your current model. You can turn off this behavior but you should start by using migrations correctly!
To turn off the behavior use:
Database.SetInitializer<YourDatabaseContext>(null);
You are using your own initializer which is most probably derived from wrong build-in initializer causing drop of your current database.