0

私はEntityFramework 4.1を使用しています。

私が達成したいのは、SaveChanges メソッドが FooEntity であるエンティティで呼び出されるたびに、最初にそれらのエンティティを更新してから削除したいということです。

以下のようにデフォルトの動作をオーバーライドしようとしましたが、目的を達成できません。Db で更新されます。ただし、DELETE ではありません。

どうすればこれを達成できますか?

public override int SaveChanges()
        {
            var entitiesMarkedAsDelete = ChangeTracker.Entries<FooEntity>()
                                    .Where(e => e.State==EntityState.Deleted);

            foreach (var e in entitiesMarkedAsDelete)
            {
                e.State = EntityState.Modified;
            }

            base.SaveChanges(); // To enforce an UPDATE first

            // Now, I try to re-mark them to DELETE
            foreach (var e in entitiesMarkedAsDelete)
            {
                e.State = EntityState.Deleted;
            }

            base.SaveChanges(); // And hope that they will be deleted

            // RESULT: 1st call of base.Savechanges() updates the entities
            //       but the 2nd call of base.Savechanges() does not make any changes on the UPDATED 
            //      entities -and they are NOT DELETED.

        }
4

1 に答える 1

1

ここでは、LINQ の怠惰な性質にだまされていると思います。

ここで作成するシーケンス:

var entitiesMarkedAsDelete = ChangeTracker.Entries<FooEntity>()
                             .Where(e => e.State==EntityState.Deleted);

.. は反復されるたびに評価されるため、2 回目に foreach を実行すると、削除された状態のエンティティがなくなるため、実際には結果が返されません。

したがって、これを修正するには、シーケンスを fx にパイプするだけです。それを呼び出す.ToListことによるリスト:

var entitiesMarkedAsDelete = ChangeTracker.Entries<FooEntity>()
                             .Where(e => e.State==EntityState.Deleted).ToList();

そうすれば、両方の foreach ステートメントが同じエンティティを反復処理し、適切に削除する必要があります。

于 2013-10-11T08:41:04.783 に答える