2017-08-10 12 views
0

E1E2の2つのエンティティが同じCodeの値を共有しているとします。私が最初に削除し、次を挿入するとします。エンティティフレームワークでのエンティティの削除と挿入

ここ

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

問題は、私はすぐにまで反映されません_contextEntityTableからE1を削除するとことである

Item.Delete(E1); 
Item.Insert(E2); 
Item.Save(); 

私は、保存します。したがって、E2の挿入はE1がまだ存在するので成功しないため、操作は失敗します。 EntityTableには変更が反映されていますか?

+1

SQLにユニークな状態を残し、チェックインしないのはなぜですか? –

+0

あなたのクエリと、SaveChanges()への呼び出しとの間に、別のプロセスまたはスレッドによって挿入することもできます。コードでこれをしないでください。 – CodeCaster

+0

delete> save> insert> save .. lol – niksofteng

答えて

0

操作の順序が間違っているようですが、これは最も効率的な方法ではないかもしれませんが、問題を処理する必要があります。

Item.Delete(E1); 
Item.Save(); 
Item.Insert(E2); 
Item.Save(); 

の順に呼び出します。

または、削除メソッドと挿入メソッドにsaveメソッドを追加して、それぞれが実行するように保存することができ、2行だけで済むようになります。

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
    Save() 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
    Save() 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

、その後、あなたはこのことができます

Item.Delete(E1); 
Item.Insert(E2); 

希望のようにそれを呼び出すことができます!私に知らせないと、私は答えを取り除きます(私は50人の担当者の下でコメントすることができないので、答えを使用しなければなりませんでした。そうでなければ、答える前にコメントを使っていました)。

+0

ありがとうございます。問題は一般的に私はDBに2回行くことを避けたいです。私はRepoにUOWパターンを使用しているため、ビジネスロジックオブジェクトは異なるオブジェクトを挿入するためにDBに何度も移動する必要はありません。 – Husain

1

各操作の後に簡単なコールSaveChangesを呼び出します。

あなたはあなたがあなたのコンテキストを初期化する(これは、両方の操作が実行されているを確認します)時にトランザクションを作りたい:

_transaction.Commit(); 

それを:

_context = new FooEntities(); 
_transaction = _context.Database.BeginTransaction(); 

あなたSave方法は、代わりにトランザクションをコミットします文脈とトランザクションを破棄することはありませんが、あなたはすでにそれを行うと確信しています;)


0サイドノートでは

、あなたがとにかく例外をスローするので:

if (existingEntity != null){ 
    throw new ArgumentException("Item alread exists.") 
} 

はなぜコード]列にunique constraintを作成していませんか?この方法でデータベースで例外がスローされます;

+0

ありがとうございます。私はこのためにDBへの往復を2回避けようとしています。一意の制約はこの単純な例では機能しますが、ソフト削除があるので私の場合はそうではありません。そして制約を受けて、APIユーザーに有用なメッセージを返すためにデータベースから取得している例外を解読する必要があります。 – Husain

+0

複数の列の上に一意の制約を設定することができます(例:Code&IsDeleted)。また、C#6では、[ExceptionFilters](https://stackoverflow.com/a/34813242/2441442)を使用すると、より良い例外を再試行するのが簡単です。往復について:典型的な読書は高価な読書ですが、これは書面よりはるかに頻繁に起こるからです)@Husain –

関連する問題