I lost all data in my tables when I update my models - ef-code-first

I use EF Code First in my solution with SQL Server Express behind it. When I update my model, I always have to delete my database before restarting my solution. I know this is because my database is no more up to date. In that case, I lose all data in my tables.
I would like to be able to update my models (for example: adding a new field) and keeping all data in my tables.
Even if I update manually my database, when I restart the solution, I get the error below:
The model backing the 'EntityFrameworkDbContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance
Any suggestions?
Thanks.

You can remove the creation of EdmMetadata table as follows.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
}
This way you can manually update the database without getting the error.
You can check out Code First Migrations

To expand a bit on my comment. This is not generally possible, nor was CF designed for this. The only way around is to manually update your tables with SQL commands AND to update the database model verification hash stored as EDMmetadata or some such in your database, before you live an update your Code first model.
To get the proper hash value you can create a temporary database and just copy your value from there.
Not pretty, but it works.

Related

ASP.NET MVC - 'no such table': AspNetUsers

I'm creating a web app that will allow users to log in to execute certain actions. I followed this tutorial (for simplicity, you can search for "Generate the database to store membership data" for the exact database setup I used).
Everything works fine in development, but when I deploy it and try to register a new user, it gives me the error:
An unhandled exception has occurred: SQLite Error 1: 'no such table: AspNetUsers'.
Is this because I need to do a 'dotnet ef database update' in deployment? If so, is there anyway I can avoid it, such that I can just deploy and have the database setup itself and be ready? The tutorial semi-talked about it by calling 'dbContext.Database.Migrate();', but I have no dbContext in the Configure() method... so I'm not sure how to fill in the gaps.
If there is any information about my code you'd like me to post, I'll be happy to post it for you. Thanks in advance!
I did happen to figure out how to fix the problem, but please bear with me on the details of the solution. It has been so long that I can only remember that Step 1 is definitely necessary, but I'm fairly fuzzy on if we also need to do Step 2. Some point down the line when I have time, I'll revisit this to confirm, but for now, I hope this will give you enough help to overcome the problem.
Step 1: Create your AspNetUsers table in your custom context class that inherits from IdentityDbContext<IdentityUser> with the following code. For the purposes of my example, I'm calling this class: CustomDbContext.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
base.OnModelCreating(modelBuilder);
}
Note: If you aren't following the guide or using this for authentication, you'd simply have your custom context class inherit from DbContext.
Step 2: In your Startup.cs, you'll need to put the following code in your Startup() method, where you are literally ensuring that the CustomDbContext database (AspNetUsers) is created and available in production.
using (var client = new CustomDbContext())
{
client.Database.EnsureCreated();
}
Note: There is speculation that you could do client.Database.Migrate() in that using statement instead according to this (credit to Thomas Schneiter for letting me know), but I have not personally tried it to see if it works. There is another SO post relating to this particular piece of code with an answer I posted.

(EF6) How can I specify a different ConnectionString to be used with Automatic Migrations?

I want to have two different SQL connections. One will leverage code-first automatic migrations to keep the database schema up-to-date. The other will do the typical website day-to-day.
I have both connection strings in my Web.config (one named "Migrator" and the other named "Agent").
How can I accomplish this?
Right now the schema is updated on the first read or write to the database, so I'm unsure where I can even set this...
In case anyone else was wondering the same thing, the way I ended up doing this was:
static MyDbContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, MyProgram.Migrations.Configuration>("Migrator"));
}
public MyDbContext() : base("Agent")
{
}
In this way whenever "MyDbContext" is first initialized or accessed it initializes my database using the "Migrator" connection string.

MVC 4 SimpleMembership - Doing it right the first time

Folks,
I just started to design a new web project. From VS2012, I generated a new Internet website project. It comes with a database that is already laid out with a few tables. This is fine.
Now, I need to extend the database with a few new tables and update UserProfile with few new fields. However, as this is going to be a new database, I don't want to enable migration steps and add code-bloat that is not really needed.
Here is the workaround I found:
Extend UserProfile with new fields as you would want to.
Add new tables in AccountModels.cs. For example,
[Table("Items")]
public class Items {
...
}
For each new table, add a DbSet field to UsersContexts class in AccountModels.cs.
public class UserContext : DbContext {
...
public DbSet<Items> Items {get; set; }
}
Delete the original database file, create a new database file with the same name, and run the application.
Voila. The new database gets filled with all the tables.
Is this the right way to do it?
Although it works, I am not really sure about step 3. I figured somehow the framework needs to know that a new table needs to be created and essentially adding a new field to UserContext triggers the creation of the new table. Is this the approach right?
Thank you in advance for your help.
Regards,
Peter
By not using code first migrations, deleting the database manually is the best thing you can do. There is also the DropCreateDatabaseIfModelChanges initializer but be careful to never use it in a release version of your app.
I would also recommend to write the DbContext in a seperate cs file. When you use the fluent api to configure the EF relations (what i would do), it can get really big. Think about putting the DAL and your models in seperate projects when your solution gets bigger. Using multiple contexts for one db can also cause problems, so naming it SomeAppContext would be better.

ASP.NET MVC4 - Error When Customize Default Accounts Models & Controller

I am in the begining of making a simple website using ASP.NET MVC4 CodeFirst Approach. The web site is built around users who are able to register, make posts etc. The existing UserProfile class was modified for the accommodation other fields (ex: FirstName, LastName etc).
When I ran the website I got a similar error:
Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Phone'.
I red that this is because the Database is not updated as the model is updated. So I set the following on the Application_Start() in Global.asax with the intention of droppnng the database always (at least until I get the hang of it).
protected void Application_Start()
{
Database.SetInitializer(new DropCreateDatabaseAlways<UsersContext>());
//Other default generated stuff below...
}
I also tryed the DropCreateDatabaseIfModelChanges, but both methods didn't drop the database.
Isn't this possible? Why is it? Am I doing some thing wrong?
I believe it would be possible to store the info in a different table and link it to this, but I prefer to keep it in one table.
Also is it a bad idea to add UserProfiles to the websites context (lets say: DatabaseContext (which has other entities like Posts, Comments etc) and change the AccountsController to use DatabaseContext instead of UsersContext?
Thanks in advance.
Have you run Enable-Migrations in the Package Manager Console? You should see a migration folder in your project, with a configuration.cs file, ensure you have enabled automatic migrations.
public Configuration(){
AutomaticMigrationsEnabled = true;
//if you drop columns - consider this carefully...
AutomaticMigrationDataLossAllowed = true;
}

How to manually update Entity framework Code first model so that it updates a database (with a new column)?

can somebody tell me how I can add a data member (col) to my mvc3 model (class) and have it update the database without having to generate everything from scratch? I'm working from code first. When I change my model then run my project I get an error stating that model has changed. Any clean and easy way to synch creating a new col/data mamber with the db/model?
Thanks!
you can use this in application start,
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDBContext>());
it will regenerate the database if your model change happens.And if you do not want to drop and create database (To incremental development) you can use SqlMigrations. http://www.hanselman.com/blog/EntityFrameworkCodeFirstMigrationsAlphaNuGetPackageOfTheWeek10.aspx

Resources