4

repo.SaveChanges()Entity Framework 5リポジトリでメソッドを公開するかどうかについて、別の開発者と話し合っています。

次のような変更を自動的に保存するリポジトリを作成することを検討しています(迅速で汚い例)。

public class Repo {
    private OurEfContext _context = new OurEfContext();

    public void PersistCustomer(Customer cust)
    {
        // update customer code here
        _context.SaveChanges(); //  <-- is this okay?
    }
}

検討している他のオプションは、次のような別のRepo.PersistChanges()メソッドを公開することです。

public class Repo {
    private OurEfContext _context = new OurEfContext();

    public void PersistCustomer(Customer cust)
    {
        // update customer code here
        // no call to _context.SaveChanges();
    }

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

私が見たほとんどの例では、2番目のパターンを使用しています。1つのパターンは他のパターンよりも「正しい」ですか?

4

3 に答える 3

8

変更のたびに保存すると、エンティティのバッチを保存できなくなります。特定のグラフ構造では、これは正当性の問題になる可能性がありますが、それ以外の場合は、CPUの負荷を高めるだけです。のコストはSaveChanges、書き込みだけでなく、コンテキストにロードされたエンティティをトラバースすることでもあります。

なぜEntityFrameworkに反対するのですか?実行してほしいこと:バッチを保存SaveChangesし、エンティティにすべての変更が加えられたら最後に呼び出します。

メソッドのPersistCustomer名前が間違っています。顧客だけでなく、すべてが永続化されます。EFを使用して単一のエンティティを永続化することはできません。あなたの抽象化(リポジトリ)は壊れています。

多くの場合、EFは、機能を追加せずに機能を削除する汎用リポジトリにラップします。それは私には決して意味がありませんでした。

于 2013-01-17T23:15:02.183 に答える
3

私は2番目の方法をサポートする傾向があります。

最初のものは保存アクションを「隠す」可能性があり、ユーザーには見栄えが良くなりますが、保存アクションの制御を失うことを忘れないでください。複数のエンティティを更新していることに気付いた場合、一度に実行するのではなく、複数の個別の変更のオーバーヘッドが発生します。つまり、実行時間が長くなります。

「SaveChanges」を冗長に呼び出すように感じるかもしれませんが、2番目の方法では、一度に複数の変更を保存できます=オーバーヘッドはありません。

不必要な行為としてパフォーマンスを向上させる能力を取り除くことによって、自分自身を制限していることに気づきます。

于 2013-01-17T23:38:00.497 に答える
1

私は2つの理由で最初の方法に移行しました:

1)時々(頻繁ではありませんが)SaveChanges()メソッドを呼び出すのを忘れました。たとえば、トランザクションもコミットする必要があり(または変更を保存したがトランザクションをコミットするのを忘れた)、理想的ではないテストでこの種のエラーが検出されなかった場合(Validate()毎回関数を呼び出さないアプローチに似ています)あなたはそれを呼ぶのを忘れることができるので、あなたはあなたの事業体の何かを変えます(これが唯一の理由ではないとしても))。

2)リポジトリインターフェイスは(テスト目的で)メモリリポジトリに変換でき、呼び出す意味がありSaveChanges()ません。標準コレクションにはこの種のメソッドがなく、実装はユーザーに対して非表示にする必要があるため、混乱する可能性があります。

コレクションを追加する必要がある場合は、リポジトリに別のメソッドを追加してImport(List<Customer> customers)実行し、その後foreach呼び出すことができます。SaveChanges()これは、いくつかの最適化された方法が存在することもユーザーにとって明らかです。

複数のリポジトリで複数の操作を実行する必要がある場合は、すべての操作をトランザクションでラップできます(トランザクションが全体としてコミットされなくなるまで、すべての変更をリレーショナルデータベースにロックして、不整合やデッドロックを回避できます)。

しかし、私は最初または2番目の方法がよくわかりません。どちらもトレードオフがあり、おそらくそれは個人的な好みの問題ですか?

于 2020-01-02T19:05:05.877 に答える