0

この設計上の問題があります。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() の後にエンティティをデタッチすると、コンテキストを破棄する必要がないようにリソースを節約できますか?

ありがとう。

4

0 に答える 0