I have to delete some rows in the database. I’m using Entity Framework 4.3 (code-first). I have a class that’s responsible for deleting the entities/rows. BUT, when I run my spec, it fails because nothing actually gets deleted. If I check the database, the items are still there… no work was done.
Here’s my test/spec:
public class when_removing_all_monkeys
{
DefaultDataContext _databaseContext;
IMonkeyRemover _monkeyRemover;
protected override void Given()
{
Database.DefaultConnectionFactory =
new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
_databaseContext = new DefaultDataContext();
_databaseContext.Database.Create();
//Builder is from nBuilder, a tool that helps create
// populated objects and lists
Builder<Monkey>.CreateListOfSize(10).Build().ToList()
.ForEach(x => DatabaseContext.Monkies.Add(x));
_monkeyRemover = new MonkeyRemover(_databaseContext);
}
protected override void When()
{
_monkeyRemover.RemoveAll();
}
[Test]
public void it_should_remove_all_the_monkeys()
{
DatabaseContext.Monkies.Count().ShouldEqual(0);
}
protected override void Cleanup()
{
_databaseContext.Database.Delete();
_databaseContext.Dispose();
}
}
And here is my class:
public class MonkeyRemover : IMonkeyRemover
{
readonly DefaultDataContext _databaseContext;
public MonkeyRemover(DefaultDataContext databaseContext)
{
_databaseContext = databaseContext;
}
#region IMonkeyRemover Members
public void RemoveAll()
{
_databaseContext.Monkies.ToList()
.ForEach(x => _databaseContext.Monkies.Remove(x));
_databaseContext.SaveChanges();
}
#endregion
}
I tried running a SQL command to delete the items, but when the spec failed, I assumed it was because the DataContext was unaware of the changes made by the raw command. However, removing them through EF’s normal channels doesn’t seem to do the trick either.
The last time I had this problem, I ended up switching to NHibernate. This time I don’t have that option.
Thoughts?
EDIT:
Just in case I’ve done something silly in my data context class, here it is for your scrutiny:
public class DefaultDataContext : DbContext
{
public DbSet<Monkey> Monkies { get; set; }
}
SOLUTION:
Thanks to @Kiff for the answer. WOW… how simple. I had left out one very influential line. I did not SaveChanges() after creating the items in the Given() section. Here’s the updated spec:
public class when_removing_all_monkeys
{
DefaultDataContext _databaseContext;
IMonkeyRemover _monkeyRemover;
protected override void Given()
{
Database.DefaultConnectionFactory =
new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
_databaseContext = new DefaultDataContext();
_databaseContext.Database.Create();
//Builder is from nBuilder, a tool that helps create
// populated objects and lists
Builder<Monkey>.CreateListOfSize(10).Build().ToList()
.ForEach(x => DatabaseContext.Monkies.Add(x));
_databaseContext.SaveChanges(); //forgot to save changes
_monkeyRemover = new MonkeyRemover(_databaseContext);
}
protected override void When()
{
_monkeyRemover.RemoveAll();
}
[Test]
public void it_should_remove_all_the_monkeys()
{
DatabaseContext.Monkies.Count().ShouldEqual(0);
}
protected override void Cleanup()
{
_databaseContext.Database.Delete();
_databaseContext.Dispose();
}
}
Try calling _databaseContext.SaveChanges() in Given() right before initializing _monkeyRemover. The change tracker may be getting confused since the monkies were added (but not saved) and then removed.