30

エンティティ フレームワークに基づいて独自のカスタム リポジトリを構築しています。また、部分ビュー モデルをエンティティ モデルとして保存できる拡張メソッドをいくつか作成しているため、独自の Add メソッドと Update メソッドを構築しています。

現在、各メソッドには、最後に呼び出される DbContext からの SaveChanges() があります。つまり、モデルごとに 1 つの呼び出しが呼び出されます。

私は MVC4 サイト用にこの基本 DAL パターンを構築しています。つまり、ほとんどの場合、1 つのモデルにアクセスしますが、そうである必要はありません。

つまり、3 つのエンティティを更新するときにモデルごとに SaveChanges() を呼び出すのはあまりにも悪い習慣ですか?それとも、最初にすべてをオブジェクト コンテキストに追加し、何らかのトランザクション コミットとして SaveChanges() を実行する必要がありますか?

4

5 に答える 5

8

SaveChanges関連するエンティティを単一のトランザクションで永続化する必要がある場合は、(トランザクションスコープなしで)複数回呼び出すことはお勧めできません。あなたが作成したのは、漏れのある抽象化です。別の作業ユニットクラスを作成するか、ObjectContext/DbContextそれ自体を使用します。

于 2012-10-26T07:55:06.780 に答える
3

各メソッドで SaveChanges() を呼び出さないことを強くお勧めします。リポジトリ パターンと作業単位を使用することは、より良い方法です。作業単位。db 呼び出しをより効率的に行うことができます。また、一部のデータが有効でない場合 (たとえば、ユーザーの詳細は問題ないがアドレスが失敗する場合)、db を汚染するのを防ぐのにも役立ちます。

ここに役立つチュートリアルがあります。

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-アプリケーション

于 2012-10-26T11:04:48.750 に答える
0

このようなシナリオでは、ここで説明する新しい最新のアプローチが推奨されます。

TransactionScopeクラスに精通している場合は、 DbContextScope. これらは本質的に非常に似ています。唯一の違いは、データベース トランザクションの代わりにインスタンスをDbContextScope作成および管理することです。DbContextしかし、 と同様TransactionScopeに、DbContextScopeアンビエントであり、ネストでき、ネスト動作を無効にすることができ、非同期実行フローで正常に動作します。

public void MarkUserAsPremium(Guid userId)  
{
    using (var dbContextScope = _dbContextScopeFactory.Create())
    {
        var user = _userRepository.Get(userId);
        user.IsPremiumUser = true;
        dbContextScope.SaveChanges();
    }
}

内では、スコープが管理するインスタンスに 2 つの方法でDbContextScopeアクセスできます。次のようにプロパティDbContextを介して取得できます。DbContextScope.DbContexts

public void SomeServiceMethod(Guid userId)  
{
    using (var dbContextScope = _dbContextScopeFactory.Create())
    {
        var user = dbContextScope.DbContexts.Get<MyDbContext>.Set<User>.Find(userId);
        [...]
        dbContextScope.SaveChanges();
    }
}

しかしもちろん、それはDbContextScope. 他の場所 (リポジトリ クラスなど)のアンビエント インスタンスにアクセスする必要がある場合は、次のように使用するDbContext依存関係を取得できます。IAmbientDbContextLocator

public class UserRepository : IUserRepository  
{
    private readonly IAmbientDbContextLocator _contextLocator;

    public UserRepository(IAmbientDbContextLocator contextLocator)
    {
        if (contextLocator == null) throw new ArgumentNullException("contextLocator");
        _contextLocator = contextLocator;
    }

    public User Get(Guid userId)
    {
        return _contextLocator.Get<MyDbContext>.Set<User>().Find(userId);
    }
}
于 2016-04-08T16:01:59.880 に答える