この設計上の問題があります。EF 汎用リポジトリに一括更新/挿入機能が組み込まれています。
その機能内で 2 つのことが発生する可能性があります: エンティティをコンテキストに追加してカウンターをインクリメントするか、実際にデータベースへの変更をコミットするだけです: SaveChanges() (カウンター == コミットのしきい値)
SaveChanges を呼び出すときは、リソースをクリアする方法として、コンテキストを破棄して再作成することも好みます。
問題は、破棄後にエンティティを更新できなくなることです。これが私の更新方法です:
public void Update(T entity, int batchSize)
{
try
{
System.Data.EntityState entityState = (System.Data.EntityState)BLHelper.GetValue(entity, "EntityState");
if (entityState == System.Data.EntityState.Detached)
this.Attach(entity);
//The next line will work so as long as QueueContextChanges() did not
//save changes and then Dispose of the context...
//After that, I'll get an exception that:
//'ObjectStateManager does not contain an ObjectStateEntry with a reference to an object...'
_context.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);
QueueContextChanges(batchSize); //Just increments a counter or calls SaveChanges()
}
catch
{
throw;
}
}
public void Attach(T entity)
{
_objectSet.Attach(entity);
}
public void QueueContextChanges(int batchSize)
{
if (_commitCount == _commitThreshold || _counter == batchSize || batchSize == 1)
{
try
{
SaveChanges();
}
catch
{
//throw;
}
_commitCount = 0;
}
else
_commitCount++;
_counter++;
}
public void SaveChanges()
{
try
{
_context.SaveChanges();
_context.Dispose();
_context = null;
_context = SelectContext<T>(); //This methods knows which context to return depending of type of T...
}
catch
{
//TODO
}
}
より良い (そして機能する) 設計を思いつきますか? 500,000 行の追加/更新中にメモリ使用量をクリアする機能は、現時点では重要です。
SaveChange() の後にエンティティをデタッチすると、コンテキストを破棄する必要がないようにリソースを節約できますか?
ありがとう。