I'm trying to create a new database using the code first concept of Entity Framework. However when running the code the database isn't created (using the DropCreateDatabaseIfModelChanges
setting), though the code is running fine. I'm seeing the following exception when I try to get something from the database.
My project is setup using a separate DataAccess
layer with an generic service and repository construction. So all my entities, repository and also database context are in a separate project within the solution.
My global.asax
file contains the following piece of code.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
This should initialise a new database if it isn't there, right?
My database context class looks like this;
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it's base class.
/// </summary>
public MyContext()
: base("MyConnectionString")
{
}
static MyContext()
{
try
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
}
}
I've created this class following several tutorials and articles on the internet. It's all new to me, but as far as I can see everything seems correct so far. So now the two entities I'm using. They're called 'Project' and 'Portfolio'. They look like this;
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
And
public class Project
{
[Key]
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public String Title { get; set; }
}
The database I'm using is running on an external server, it came with the hosting provider I'm using. I've got a SQL Server database up and running and the connection string to the database is in the web.config
of the website project. I've already tried removing the database and let the code recreate it, which unfortunately didn't work. Am I missing something obvious here? Or could it be a simple thing as access-rights to the server to create databases?
Note: When I run the Database-Update -Script
command to generate SQL code, it seems that the correct SQL statements to create all tables are created.
UPDATE 1: Okay, thanks to some comments I came a bit further. I've added two properties to my entities to force some changes and I've also created an custom initializer like this;
public class ForceDeleteInitializer : IDatabaseInitializer<MyContext>
{
private readonly IDatabaseInitializer<MyContext> _initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
public ForceDeleteInitializer()
{
//_initializer = new ForceDeleteInitializer();
}
public void InitializeDatabase(MyContext context)
{
//This command is added to prevent open connections. See http://stackoverflow.com/questions/5288996/database-in-use-error-with-entity-framework-4-code-first
context.Database.ExecuteSqlCommand("ALTER DATABASE borloOntwikkel SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
_initializer.InitializeDatabase(context);
}
}
I've also removed the initializer from the constructor of my context, so this mean i've remove this line of code;
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
After that i've added these three lines to my Global.asax file;
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
When debugging i'm now getting this exception;
This gives me the following information:
- InnerException says: The provider didn't return a ProviderManifestToken
- InnerException in the InnerException says: "For this operation an connection to the masterdatabase is required. A connection can't be made width the 'master'-database because the original connection is opened and the references has been removed from the connection. Please provide a non-open connection"
After these action the database is inaccessible, so most likely deleted..
What can possibly be done about this? It's most likely that I can't access the master database because my hostingprovider won't give me the proper access right ofcourse.