2012-03-14 95 views
1

我必須刪除數據庫中的一些行。我使用Entity Framework 4.3(代碼優先)。我有一個負責刪除實體/行的類。但是,當我運行我的規格時,它失敗了,因爲沒有任何東西被刪除。如果我檢查數據庫,項目仍然存在......沒有工作完成。EF 4不會刪除實體

這裏是我的測試/規格:

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(); 
    } 
} 

這裏是我的課:

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 
} 

我試圖運行SQL命令來刪除的項目,但在規格失敗了,我以爲這是因爲DataContext不知道原始命令所做的更改。但是,通過EF的正常渠道刪除它們似乎也無法做到這一點。

我最後一次遇到這個問題,最後我切換到了NHibernate。這次我沒有這個選擇。

想法?

編輯:

以防萬一,我已經做了一些愚蠢的在我的數據上下文類,這裏是你的推敲:

public class DefaultDataContext : DbContext 
{ 
    public DbSet<Monkey> Monkies { get; set; } 
} 

SOLUTION:

謝謝以@Kiff爲答案。哇...多麼簡單。我忽略了一條非常有影響力的路線。在Given()部分中創建項目後,我沒有SaveChanges()。下面是更新規格:

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(); 
    } 
} 
+1

你是否檢查過實體是否有狀態EntityState.Deleted?你的代碼或數據庫中肯定有問題(即觸發防止刪除)。 – 2012-03-14 16:14:39

+0

@TomasVoracek,每次運行規範時都會創建新的數據庫,所以我無法想象觸發器或數據庫中的某些內容會阻止刪除操作。我正在檢查entityState。 – 2012-03-14 16:33:13

+0

您的示例代碼有時不一致,有時候您會編寫'_databaseContext'有時候'DatabaseContext' ...也許您在測試中使用了兩個DbContext ...可以清理您的示例嗎? – nemesv 2012-03-14 16:48:42

回答

3

在初始化_monkeyRemover之前嘗試在Given()中調用_databaseContext.SaveChanges()。自從monkies被添加(但未保存)然後刪除後,更改跟蹤器可能會變得困惑。

1

試試這個:

foreach(var monkey in context.Monkies) 
{ 
    _databaseContext.Monkies.DeleteObject(monkey); 
} 
_databaseContext.SaveChanges(); 
+1

我在Google中看到了.DeleteObject(),但這不是DbSet <> api中的選項。 DbSet <>上遠程關閉的唯一方法是.Remove()。 – 2012-03-14 16:19:12

1

從你的代碼,它看起來像你正在做以下幾點:1。 創建新對象 2.刪除在步驟1

創建的對象

確定EF不應該在這種情況下與數據庫進行交互,因爲您的對象從未存儲在數據庫中。