大きな永続コレクションをすばやくクリアするにはどうすればよいですか?

私は Bars コレクションを持つエンティティ Foo を持っています。

このコレクションは非常に大きく(たとえば、2万の要素があり、ツリービューに表示されるので完全に読み込む必要があります)、その要素は Foo のいくつかのパラメータに基づいて自動的に生成されますユーザーはWPF MVVMアプリケーションを使用して変更できます(すべての処理はクライアントで行われます)

結果に満足した後、彼はsaveをヒットし、 DbContext.SaveChanges()が呼び出されます。

Generating Bars implies clearing the collection, then doing a bunch of calculations and adding the new elements. When this is a new, non-persistent Foo, it's no problem because I can just call 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();
}

The problem with this solution is that it doesn't scale. Calling Entry(bar).State = EntityState.Detached when there are many entities loaded is even slower than just calling context.Set().Remove(bar) and letting EF do the deletes one by one, so it defeats the purpose of the workaround.

So, my question is: Is there any efficient way to make EF believe the collection is actually empty?

まったく別の方法で行うべきですか?

1

1 答え

まあ、思ったよりも簡単でした。

私はこの行を置き換えた:

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

これは(私は多かれ少なかれ同等だったと思った):

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

そして今、合理的な時間に完了します。

1
追加された