18

ASP.NET MVCアプリケーションでは、データアクセスに作業単位とリポジトリパターンを使用しています。

作業単位クラスとその内部で定義されたリポジトリを使用して、コントローラー内の関連するエンティティのセットをフェッチしています。私の初心者の知識では、ビジネスモデルを取得してビューモデルに変換する2つの方法を考えることができます。

  • リポジトリはビジネスモデルをコントローラーに返します。このモデルはビューモデルにマップされているか、または
  • リポジトリ自体がビジネスモデルをビューモデルに変換してから、コントローラに返されます。

現在、最初のアプローチを使用していますが、多くのプロパティを持つビューモデルでは、コントローラーコードが見苦しく長く見え始めました。

一方、私のリポジトリはUserRepositoryと呼ばれているので(たとえば)、単一のビューにのみ役立つモデルではなく、ビジネスモデルを直接返す必要があると考えています。

これらのうち、大規模なプロジェクトに適しているのはどれだと思いますか?別の方法はありますか?

4

3 に答える 3

22

リポジトリは、ビューモデルではなく、ドメインモデルを返す必要があります。モデルとビューモデル間のマッピングに関しては、個人的にAutoMapperを使用しているため、別のマッピングレイヤーがありますが、このレイヤーはコントローラーから呼び出されます。

典型的なGETコントローラーアクションは次のようになります。

public ActionResult Foo(int id)
{
    // the controller queries the repository to retrieve a domain model
    Bar domainModel = Repository.Get(id);

    // The controller converts the domain model to a view model
    // In this example I use AutoMapper, so the controller actually delegates
    // this mapping to AutoMapper but if you don't have a separate mapping layer
    // you could do the mapping here as well.
    BarViewModel viewModel = Mapper.Map<Bar, BarViewModel>(domainModel);

    // The controller passes a view model to the view
    return View(viewModel);
}

もちろん、繰り返しのマッピングロジックを回避するために、カスタムアクションフィルターを使用して短縮することもできます。

[AutoMap(typeof(Bar), typeof(BarViewModel))]
public ActionResult Foo(int id)
{
    Bar domainModel = Repository.Get(id);
    return View(domainModel);
}

AutoMapカスタムアクションフィルターはOnActionExecutedイベントをサブスクライブし、ビュー結果に渡されたモデルをインターセプトし、マッピングレイヤー(私の場合はAutoMapper)を呼び出してビューモデルに変換し、ビューの代わりに使用します。もちろん、ビューはビューモデルに強く型付けされています。

于 2012-07-13T12:10:06.577 に答える
4

あなたのリポジトリはビジネスモデルを返すべきだと思います。

次に、 Automapperなどのツールを使用して、プロパティをビューモデルに自動的にマッピングし、手動のマッピングコードを取り除くことができます。このアプローチは、ビジネスエンティティのすべてのプロパティを公開したくない場合、または完全な構造をビューに公開したくない場合に非常に便利です。

また、この投稿が役立つ場合があります。ここでは、手動のマッピング呼び出し(一種)を取り除くことができ、ビューモデルなどの使用方法(私の意見では)の良い例を提供します-または少なくとも何らかのインスピレーションを得ることができます。

投稿からの抜粋(属性はビジネスモデルからビューモデルへの変換を行います):

[AutoMap(typeof(Product), typeof(ShowProduct))]
public ActionResult Details(int id)
{
    var product = _productRepository.GetById(id);

    return View(product);
}
于 2012-07-13T12:08:21.820 に答える
0

他の回答で述べたように、AutoMapperは優れたソリューションです。

ただし、エンティティをViewModelに、またはその逆に変換する拡張メソッドを作成することもできます。おそらくこれは、エンティティクラスとモデルクラスが少ない小規模なプロジェクトに適しています。

例:

public static class Extension
{
    public static MyViewModel ToModel(this MyEntity x)
    {
        return new MyViewModel
        {
            Id = x.Id,
            Name = x.FirstName + " " + x.LastName,
            UserId = x.User?.Id
        };
    }
}

そして使用するには:

// NOTE: "MyEntityTable" is of type "MyEntity"

List<MyViewModel> toReturn = _db.MyEntityTable
                  .Include(x => x.User) // Include other tables to join.
                  .Select(x => x.ToModel())
                  .ToList();
于 2019-09-26T01:20:03.837 に答える