10

行数を気にしないように EF に指示する方法はありますDELETEUPDATE?

データベースから行を削除しようとしていますが、行が存在しないため、EF は例外をスローします: DbUpdateConcurrencyException.. 0 行が影響を受けたと言っています。これは正しいです -> 行は削除されませんでした。しかし、それはまったく問題ありません..データがないからです。

その行が存在するかどうかを確認するためにDBへのラウンドトリップを実際に行いたくありません..存在する場合は..それを試して削除します。

ブロック内の例外を飲み込もうとすると、try / catch削除しようとしている残りのアイテムがデータベースに送信されませんSaveChanges()...これは悪いことです。

例えば。

Delete(new Foo(1));
Delete(new Foo(2));
Delete(new Foo(3));
SaveChanges(); // <-- Throws the exception.

// DB Trace : DELETE FROM Foo WHERE Id = 1;

それだけです..削除しようとしているレコード2または3を示すトレースはありません..例外がすべてを停止するため:(

何か案は?

アップデート

どのように機能しDeleteますか?コードは次のとおりです...(簡略化され、厳密に型指定されています)

public void Delete(Foo foo)
{
    if (foo == null)
    {
        throw new ArgumentNullException("foo");
    }

    Foo attachedEntity = Context.Set<Foo>().Local.FirstOrDefault(x => x.Id > 0);

    if (attachedEntity != null)
    {
        // Entity already in object graph - remove entity.
        Context.Set<Foo>().Remove(attachedEntity);
    }
    else
    {
        // Entity not in object graph, attach and set EntityState to Deleted.
        Context.Entry(foo).State = EntityState.Deleted;
    }
}
4

2 に答える 2

2

EF の動作は正しいと思います。単純に、DB に存在するオブジェクトに対してのみコマンドを実行する必要があります。「試してみて、どうなるか…」のようなシナリオには向いていません。オブジェクトがDBに存在することを確認できず、ラウンドトリップを行いたくない場合(特にオブジェクトが独立した関連付けに参加している場合、切り離されたオブジェクトを削除すると他のいくつかの落とし穴が生じる可能性があるため、これが最善のアイデアだと思います)使用する必要がありますDbContext.Database.SqlCommandストア プロシージャを実行します。

正しい処理方法はここDbUpdateConcurrencyExceptionで説明されています=>各例外の後、競合を解決し(あなたの場合、問題のあるエンティティをDbContextから削除することを意味します)、再度実行する必要があります。SaveChanges

于 2011-02-17T09:28:24.910 に答える
-1

実際には、次のように設定することで、これらの種類の問題を無視できます。

db.Configuration.ValidateOnSaveEnabled = false;

dbDbContext インスタンスはどこにありますか。

明らかに、これを行うときに何をしているのかを知っておく必要がありますが、EF ではないデータベースを更新するほとんどのアプローチには、変更の追跡/検証がなく、単純にデータベースに更新/挿入/削除を発行するだけです。最初に何かをチェックするので、基本的には EF にそのように動作するように指示しているだけです。

于 2012-08-02T04:53:09.413 に答える