2

ASP.NET MVC 2 と Entity Framework を使用して、初めての Web アプリケーションを構築中です。リポジトリ パターンを使用しています。Stack Overflow や他の Web サイトで収集した情報によると、コンセンサスは、ドメイン モデル オブジェクトごとに 1 つのコントローラーと、集約ルート オブジェクトごとに 1 つのリポジトリーを持つことです。

問題は、集約ルート リポジトリを介して非ルート集約オブジェクトにアクセスする方法です。私が扱っている例では、Customer モデルと Boat モデルがあります。ボートは顧客への FK 参照でのみ存在でき、ボートは顧客のコンテキスト内でのみ参照する必要があります。これにより、これら 2 つのオブジェクトを含む集約があり、Customer がルートであると信じるようになりました。

これで、Boats コントローラーに Edit アクション メソッドがあります。

public class BoatsController : Controller
{
    private ICustomersRepository customersRepository;
    public BoatsController(ICustomersRepository customersRepository)
    {
        this.customersRepository = customersRepository;
    }   
    public JsonResult Edit(int id, FormCollection collection)
    {
        var boat = customersRepository.GetBoat(id);
        // Update boat
    }
}

私の質問は、リポジトリ内の Boat オブジェクトを取得するにはどうすればよいですか?

public class SQLCustomersRepository : ICustomersRepository
{
    DatabaseEntities db = new DatabaseEntities();

    public Boat GetBoat(int id)
    {
        return db.Boats.SingleOrDefault(x => x.ID == id);

        // OR

        return db.Customers.Where(x => x.Boats.Any(y => y.ID == id)
                           .Select(x => x.Boats.FirstOrDefault(y => y.ID == id);
    }
}

Customers リポジトリから db.Boats を参照することはできますか? これは最もクリーンなように思えますが、FakeCustomersRepository を変更して顧客とボートのリストを作成する必要があることを意味します。

db.Customers を介してボートにアクセスする方が合理的に思えましたが、LINQ クエリで自分自身を繰り返さずに単一のボート オブジェクトを返す方法がわかりませんでした。

まだ学ぶべきことがたくさんあることはわかっているので、正しい方向に向けていただければ幸いです。

ありがとう!

4

2 に答える 2

1

私の意見では、抽象インターフェースやモデルについてではなく、実装の詳細について話していると思います。インターフェイスは次のようになります。

public interface ICustomersRepository
{
    //... other methods
    Boat GetBoat(int id);
    //... other methods
}

そして、このようなモデル:

public class Customer
{
    //... other stuff
    ICollection<Boat> Boats; // or another collection type
    //... other stuff
}

私の意見では、ICustomerRepository を完全に異なるものに実装し、基礎となるデータ ストレージに関して最適な実装を見つけることはSQLCustomersRepository、デザイン ルールに反するものではありません。FakeCustomersRepository

SQL-DB の Boat テーブルに主キーがあるように見えるので、私は間違いなくこれを利用して最初のオプションを実装します。return db.Boats.SingleOrDefault(x => x.ID == id);

ただし、 に Boat コレクションを含める必要はありませんFakeCustomersRepository。Customers のリストを取得し、各 Customer の Boats コレクションにテスト ボートを入力する方が簡単な場合は、そうではありませんか? この場合、GetBoatでの実装は、FakeCustomersRepository説明した 2 番目の LINQ クエリで実装できます。

MVC での単体テストは、特定のリポジトリ実装をテストするのではなく、ビジネス ロジックをテストすることを意図していることに注意してください。ビジネス アクションは、さまざまなドメイン オブジェクトとリポジトリ メソッド呼び出しのチェーンです。単一のリポジトリ メソッドが本来の機能を実行する場合 (たとえば、GetBoat実際に正しい ID を持つボートを返す場合) は、後で統合テストを行って、データベース呼び出しが適切に機能することを証明する必要があります。

于 2010-08-06T12:23:48.423 に答える
0

なぜボートのリポジトリを持っていないのですか?

Boat が AggRoot の場合、別のリポジトリが必要です。

于 2010-08-05T19:09:37.350 に答える