For testing purposes I would like to manually be able to drop and recreate a DB using EF CodeFirst CTP5. How would I do this?
-
you can use the Database.SetInitializer, read in the comments here weblogs.asp.net/scottgu/archive/2010/08/03/…Kris Ivanov– Kris Ivanov2011-02-06 03:28:22 +00:00Commented Feb 6, 2011 at 3:28
-
You'll regularly get the following exception though: Cannot drop database "..." because it is currently in use. Just restart VisualStudio and you're good. This CodeFirst feature is still pretty unstable.RedGlyph– RedGlyph2011-02-06 17:27:38 +00:00Commented Feb 6, 2011 at 17:27
Add a comment
|
3 Answers
The DbDatabase class available as a property on your DbContext object offers a set of methods for directly working with database. You can use the Create and Delete method for this matter:
using (var context = new YourContext())
{
context.Database.Delete();
context.Database.Create();
// Or
context.Database.CreateIfNotExists();
}
3 Comments
Marino van der Heijden
And don't forget to close any connection to your database (from within Visual Studio or so) otherwise you'll get an exception saying the database is in use...
Greg
Calling Database.Connection.Close() before Database.Delete() doesn't help. You still get the message that the database is in use.
mejdev
Greg, that's because the database really is in use. You might have it open in Server Explorer--try closing that connection first.
This works for me but not dave answer with entity framework 5.0. You will have to trigger a database trip that like a query in order to trigger the action.
Global.asax
Database.SetInitializer<MedicalVarianceDataContext >(new DataInitializer());
Elsewhere
public class DropDatabaseInitializer<T> : IDatabaseInitializer<T> where T : DbContext, new()
{
public DropDatabaseInitializer(Action<T> seed = null)
{
}
protected virtual void Seed(T context) { }
public void InitializeDatabase(T context)
{
if (context.Database.Exists())
{
context.Database.ExecuteSqlCommand("ALTER DATABASE " + context.Database.Connection.Database + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
context.Database.ExecuteSqlCommand("USE master DROP DATABASE " + context.Database.Connection.Database);
}
context.Database.Create();
Seed(context);
}
}
I guess you will also need to add context.savechanges();
protected override void Seed(MedicalVarianceDataContext context)
{
new List<ViewLookUpIndividualUnit>{
new ViewLookUpIndividualUnit{ MvrsIndividualUnit="Clinic" ,Active=true}
}.ForEach(k => context.ViewLookUpIndividualUnits.Add(k));
base.Seed(context);
context.SaveChanges();
}
2 Comments
hidden
I added an edit on Dave but dont know if it will take place. So here.
Leniel Maccaferri
Beware that if your database name contains hyphens you'll need to do this:
[My-DatabaseName-with-hyphens] in the ExecuteSqlCommand part.I realize this is dated but I couldn't get the accepted solution working so I rolled a quick solution...
using System;
using System.Data.Entity;
namespace YourCompany.EntityFramework
{
public class DropDatabaseInitializer<T> : IDatabaseInitializer<T> where T : DbContext, new()
{
public DropDatabaseInitializer(Action<T> seed = null)
{
Seed = seed ?? delegate {};
}
public Action<T> Seed { get; set; }
public void InitializeDatabase(T context)
{
if (context.Database.Exists())
{
context.Database.ExecuteSqlCommand("ALTER DATABASE " + context.Database.Connection.Database + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
context.Database.ExecuteSqlCommand("USE master DROP DATABASE " + context.Database.Connection.Database);
}
context.Database.Create();
Seed(context);
}
}
}
This works for me and supports seeding easily.