2011-10-27 81 views
1

我有一個實體FooBars集合。如何快速清除大型永久性集合?

這個集合是相當大的(比如,20,000個元素,是的,它需要完全加載,因爲它顯示在TreeView中),並且元素是根據Foo的一些參數自動生成的,用戶可以使用WPF MVVM應用程序(所有處理都發生在客戶端)進行更改

對結果滿意後,他點擊保存,並調用DbContext.SaveChanges()

生成Bars意味着清除集合,然後進行一堆計算並添加新元素。如果這是一個新的,非持久性Foo,這是沒有問題,因爲我可以叫foo.Bars.Clear()

的問題是,這樣做與已經持久實體導致EF設置bar.Foo = null中的所有元素,而非將其刪除。

我的解決辦法是這樣的:

void Regenerate() 
{  
    if (fooIsPersistent) 
    { 
     foreach (var bar in foo.Bars.ToList()) 
      context.Entry(bar).State = EntityState.Detached; 
     deleteOnSave = true; 
    } 
    else 
     foo.Bars.Clear(); 
    AddTheNewCalculatedElements() 
} 

void Save() 
{ 
    if (deleteOnSave) 
     context.Database.ExecuteSqlCommand("delete Bar where Foo = @Id", param); 
    context.SaveChanges(); 
} 

這種解決方案的問題是,它不能擴展。當有很多實體加載時調用Entry(bar).State = EntityState.Detached甚至比調用context.Set<Bar>().Remove(bar)還要慢,並且讓EF逐個執行刪除操作時速度更慢,所以它違背瞭解決方法的目的。

所以,我的問題是:是否有任何有效的方法來使EF相信集合實際上是空的?

或者我應該以完全不同的方式做到這一點?

回答

1

好吧,這比我想象的要容易。

我換成這一行:

context.Entry(bar).State = EntityState.Detached; 

與這一個(我認爲是或多或少相當於):

((IObjectContextAdapter)context).ObjectContext.Detach(bar); 

現在它在合理的時間內完成。