Entity Framework not creating Tables - sql-server

I really have no luck with the EF every time. This time it looks like this:
First time i created a context i had an error like:
Invalid object name 'dbo.TableName1'
After this setting the Database Initializer to CreateDatabaseIfNotExists T it did the trick.
Next i created a different context, which was changed at some point of the development. So this time i keep getting this error:
The model backing the 'NewContext' context has changed since the database was created.
I found a solution to set the Database Initializer to null, but after this i keep getting the first error:
Invalid object name 'dbo.TableName2'
I also tried to set the the initializer to DropCreateDatabaseIfModelChanges and DropCreateDatabaseAlways, and these settings throw the exception:
Cannot drop database "DatbaseName" because it is currently in use
I think I already tried everything i found on the Web (there are many topics of this kind) but none helped me with it.
Dropping the Database didn't help, nor changing from Local File Database to SQL Server 2014 Exspress. The same exception is thrown. Any ideas?
Edit1:
Working context:
public class ProfilesContext : DbContext
{
public ProfilesContext() : base("DefaultConnection")
{
}
public DbSet<Profile> Profiles { get; set; }
public DbSet<PrevilegedContact> PrevilegedContacts { get; set; }
}
Failing context:
public class PlacesContext : DbContext
{
public PlacesContext()
: base("DefaultConnection")
{
}
public DbSet<Place> Places { get; set; }
public DbSet<Price> Prices { get; set; }
public DbSet<Photo> Photos { get; set; }
public DbSet<Comment> Comments { get; set; }
}

For what you are doing, it seems you have 2 options for your initializer. There is Migrations and there is DropCreateDatabaseIfModelChanges.
Migrations will give control over updating the database tables when your models change and allow you to preserve data. You can configure it to allow data loss or not. Very useful during development time if you already have test data in there.
DropCreateDatabaseIfModelChanges will simply drop the database each time you make model changes and recreate it with the new schemas.
You are getting the error message
Cannot drop database "DatbaseName" because it is currently in use
because you have more than likely browsed the table in your server explorer and have an open connection to the database. You can close the connection using the right click context menu in server explorer.
If you want a video overview on Migrations there is a free video by Scott Allen & Pluralsight. This is MVC4 but the Entity Framework section does cover Initalizers. If you want an updated one for MVC5 to include multiple Contexts etc, it does exist but you would need to take the Pluralsight free trial to get access to it.

I agree with James. Good point about checking Server Explorer. Right-click the database and choose Close Connection or at least check that there is a red X indicating the connection is closed. The link below is a great tutorial on the basics with Code First Migrations. The link is directly to the page within the tutorial that talks about making model changes and how to make EF happy again! http://www.asp.net/mvc/tutorials/mvc-5/introduction/adding-a-new-field. I prefer using Migrations. You would use the Package Manager Console and 1) Enable Migrations, 2) Add a migration, 3) Update the database. If in development, use LocalDb if possible, and use the Seed method in the Configuration class to prepopulate the database.

Related

Data table is not generated when I attempt to add a connection

I'm following a guide for creating a simple code-first MVC, which uses data context scaffolding. After creating a model class file and adding a scaffolded item to the project, it instructs me to go to server explorer, hit "new connection", enter (localdb)\mssqllocaldb and from there, select my database name (PlanetContext (CodeFirstFinal.Models). After hitting "ok", I should be able to expand the tables in my server explorer and see the planet data table. However, my tables folder is empty. I followed the tutorial to the letter, so I'm unsure why this is happening.
Here is the code in my model:
namespace CodeFirstFinal4.Models
{
public class Planet
{
public int PlanetID { get; set; }
public string Name { get; set; }
}
public class PlanetContext: DbContext
{
public DbSet<Planet> Categories { get; set; }
}
}
As this is a very simple app, this is the only code so far, besides the scaffolded view. (For that, I right-clicked my project, selected "add scaffolded item" and MVC 5 Controller with views using EntityFramework. I then entered my model class, which is:
Planet (CodeFirstFinal4.Models)
and my data context class, which is: PlanetContext (CodeFirstFinal4.Models).
I'm not sure how helpful this information is, but I'm including it in case it helps. I'm pretty sure that the MvcScaffolding package is installed correctly, as well as EntityFramework. However, I simply can't get the data table to be generated after right clicking 'connect to database' under server explorer, entering my local server name, and selecting the database. Below is a screenshot of the tutorial, where his table shows up under the tables folder, within server explorer. Does anyone know what might be causing the failed generation of my own data table?

Code first migrations database error

I used this pluralsight video on MVC code first migrations to keep my default MVC IdentityDb context and create another context for custom tables. Since then I get an error trying to connect connecting to the database online:
CREATE DATABASE permission denied in database 'master'.
.........
It works locally. My connection string are correct and my context classes point to the right connection string name:
public class IdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static IdentityDb Create()
{
return new IdentityDb();
}
}
public class CustomDb : DbContext
{
public CustomDb() : base("DefaultConnection") { }
public DbSet<Inquiry> Inquiry { get; set; }
public DbSet<Product> Product { get; set; }
}
Connection string:
<add name="DefaultConnection" connectionString="server=***.db.1and1.com; initial catalog=***;uid=***;pwd=***" providerName="System.Data.SqlClient" />
I've read that the connection string name should be the same as the context class name but since I have two contexts I need a common name (DefaultConnection) which I've specified in the contexts.
It works connecting to my local database but not when its online so I did wonder if this would relate to the migration history table being up to date online and EF 6 trying to update the database but the entries in the migrations table match.
Any help appreciated.
* UPDATE *
I tried resetting the EF migrations with this guide thinking if the migrations where out of sync with the online DB it could result in EF trying to re-create the database causing this issue. However the problem still persists!
I have now added these lines to my context constructors respectively:
Database.SetInitializer<IdentityDb>(null);
Database.SetInitializer<CustomDb>(null);
This has stopped the error but kind of defeated the purpose of EF because I now have to remove it when creating migrations and manually script the changes to the online DB, then put it back in for the site to work online.

Entity Framework 6 - How to update customer's database with CodeFirst migration

My team develops an application which deploys MSSQL database at customer's system. We encountered a problem with using migrations to update the customer's database structure .
We can't use automated migrations because more than one instance of the app can run on the same database so if one of instances gets updated and therefore changes the model and therefore the structure of database the others change it back so neither of them can work on the database.
We can't use nonautomated migrations because we have no access to customer's database to run the update-database command.
The question is what's the best approach to keep the database and the model always up to date on the level of code ?
You have to use the migrate to latest version strategy. This apporach allows you to automatically update the database when the model is changed:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, MyMagicDatabaseConfiguration>()`);
public class MyMagicDatabaseConfiguration : DbMigrationsConfiguration<MyDbContext>
{
public MyMagicDatabaseConfiguration()
{
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
}
}
// !!Force the initialization. this will execute the update!!
MyDb.Context.Database.Initialize(true);
This works fine if you are using MS SQL Server
The problem you are using MySql you have to do everything by your self!:
var migrator = new DbMigrator(new DbMigrationsConfiguration ());
migrator.Update();
// In the migrtaions directory:
public partial class MyMigration : DbMigration
{
public override void Up()
{
AddColumn("dbo.MyTable", "AnyName", c => c.Boolean(nullable: false));
}
public override void Down()
{
DropColumn("dbo.MyTable", "AnyName");
}
}
This is not an easy work and I do not recommeded you to do it. Just use SQL Server apporach this will safe your time.
one note more: Magic migration sometimes does not working(Complex changes with keys), if the changes can not be handled automatically.
You can also use migration to a target version:
var configuration = new DbMigrationsConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Update("HereMigrationId");
var scriptor = new MigratorScriptingDecorator(migrator);
var migrationScript = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: "HereMigrationId");
In your case you need migration to target version.
with the decrator you can modifiy the migration script during the migration.

MVC4 + EF5: field of type Bit doesnt get updated in Database

i have read a lot about a problem appearing with the change from ObjectContext to DbContext concerning the update mechanism.
But unfortunatelly this tips didnt solved my problem.
So i start a short summary whats my environment:
VS2012
MS SQL Express 2008 R2 (v10.50)
.NET 4.0
MVC4 (Internet Application Template)
EF5
Since i use the CodeFirst approach, i extended the UserProfile table with an simple bool field and called the update-database accordingly.
[Required]
public bool IsEmailApproved { get; set; }
When i search in the DB Context and find a user:
UserProfile user = ctx.UserProfiles.FirstOrDefault(u => u.SomeField == Id);
the Entity.State is Unmodified, like it should be.
Then i start updating:
user.UserName = DateTime.Now.ToString();
user.IsEmailApproved = true;
and the State changes immediatelly to Modified - also nothing special.
But on the
ctx.SaveChanges();
the database just receives the text field update, not the BIT udpate.
Can anybody help me out with an explanation or a hint, what i make wrong?
Because im almost sure, that the mistake is on my side, otherwise i would have found exact the same questions here...
Many thanks in advance!

EntityFramework unit test example

I just solved my own question, but thought I'd might still be helpful for others to read so decided to post it anyway.
I am trying to get started with azure development and am currently at the stage of getting the database up and running. After a few hickups I achieved the following:
installed VS2012, MSSQLSERVER2012, Azure SDK .NET, EntityFramework 6.0.0 alpha and a bunch of other things
wrote my first entities (code first) and generated a database out of it.
The last thing I'd like to see before I pick up the next challenge is to actually add something to my newly created database first. I'd thought the easiest way would be writing a test in nunit.
Here's what I got so far...
The entity class User:
namespace Models.Users
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
}
The entity class UsersDb:
using System.Data.Entity;
namespace Models.Users
{
public class UsersDb : DbContext
{
public DbSet<User> Users { get; set; }
}
}
Generated the database with the following PS commands:
enable-migrations -ProjectName Models -ContextTypeName Models.Users.UsersDb
add-migration -ProjectName Models Initial
update-database -ProjectName Models
Finally, I wrote the following unit test
using Models.Users;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class DatabaseTests
{
[Test]
public void AddUserTest()
{
var users = new UsersDb();
var user = new User
{
Id = 1,
Name = "test",
EmailAddress = "test#gmail.com"
};
users.Users.Add(user);
users.SaveChanges();
}
}
}
That test runs, but throws an exception I can't figure out.
System.InvalidOperationException : The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' for the 'System.Data.SqlClient' ADO.NET provider could not be loaded. Make sure the provider assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
Solution
What I had to do to solve this, is open NuGet management (right click solution) and press the manage button on EntityFramework. In the dialog add a checkbox in front of your test solution, rebuild and go.
Now, I have a very small solution that creates a new user via a unit test and saves it into my database. A nice startup project which I can now start extending.
Solved the question while typing the question itself. Thought i'd still be useful as a reference for others.

Resources