1

次のように DB にマッピングするItemモデルがあります。

public class Item
{
    public int ItemId { get; set; }
    public DateTime Created { get; set; }
    public string Title { get; set; }
}

これらのアイテムのリストを表示するために、次のようにItemSummaryViewModelを作成しました。

public class ItemSummaryViewModel 
{
    public int ItemId { get; set; }
    public string Title { get; set; }   

    public ItemSummaryViewModel(Item item)
    {
        this.ItemId = item.ItemId;
        this.Title = item.JobTitle + " " + item.Created.ToString("ddd d MMM HH:mm");
    }
}

また、次のようにList< Item >を取得してList< ItemSummaryViewModels > を返すクラスも作成しました 。

public class ItemSummaryViewModelList : List<ItemSummaryViewModel>
{
    public ItemSummaryViewModelList(List<Item> items)
    {
        foreach (Item i in items)
        {
            ItemSummaryViewModel itemSummary = new ItemSummaryViewModel(i);
            this.Add(itemSummary);
        }
    }
}

最後に、コントローラーを使用して、次のようにリストをビューに渡します。

    public ActionResult Index()
    {
        //IEnumerable<ItemSummaryViewModel> itemsummaries = new IEnumerable<ItemSummaryViewModel>();

        List<Item> ListOfItems = db.Items.ToList();

        ItemSummaryViewModelList ListOfItemViewModels = new ItemSummaryViewModelList(ListOfItems);

        return View(ListOfItemViewModels);
    }

私の質問は:

  1. これを行うためのより効率的な方法または「ベストプラクティス」の方法はありますか?

  2. DB モデル ( Item ) のリストを表示可能なビュー モデル ( ItemSummaryViewModels ) のリストに変換するために、現在、リスト内の各アイテムを繰り返し処理し、個別に変換しています。これを行うより効率的な方法はありますか?

基本的に、DB にクエリを実行し、データを ViewModel に割り当ててリストとして表示します。私は少し「家を回っている」と感じずにはいられず、これを行うためのより効率的な方法または「ベストプラクティスの方法」があるかもしれません.

より良い方法はありますか?

ありがとう

4

3 に答える 3

1

効率に関しては、実装が最も簡単なソリューションが実際には非常に遅いことがわかるまで、心配する必要はありません。最初に機能させてから、実際に必要な場合にのみ最適化してください。明らかに、あなたが示した例では、ビューが必要とするアイテムのサブセットのみをクエリして変換する機会があります(すべてかもしれませんが、ページングしている可能性がありますか?)

構造的には、学術的かつ専門的に正しい答えは、データベース エンティティを表すオブジェクトのセット、「ドメイン」またはビジネス オブジェクトを表すオブジェクトのセット、およびすべての MVC モデルを表すオブジェクトのセットを持つことだと思います。ただし、正確なシナリオによっては、これを単純化できます。

  1. ビジネス オブジェクトとデータベース エンティティの間に非常に近いマッピングがあり、データベースが大幅に変更される可能性がほとんどない場合は、両方に対して 1 つのクラスを使用できます。

  2. ビジネス・オブジェクトに非常にきれいにマップされる非常に単純なビューのセットがある場合は、ビジネス・オブジェクトをモデルとして使用できる可能性があります。ビューが生のビジネス オブジェクトを Web ページにスプラットするだけでない限り、モデルは通常、現在の例よりも複雑にする必要があると思います。

その特定のケースについては、@CorrugatedAir に同意し、独自の List クラスを作成するのではなく、単純な List を使用できます。より単純にしたい場合は、List を使用して ItemSummaryViewModel クラスの作成をスキップすることもできます。

ただし、アプリケーション全体で一貫性を保つようにしてください。そのため、データベース エンティティをビジネス オブジェクトとして使用できない状況が見つかった場合は、すべてのインスタンスに個別のセットを用意し、それらの間にマッパーを配置することをお勧めします。

于 2013-03-08T16:04:41.293 に答える
1

LINQ select を使用してみてください。

List<ItemSummaryViewModel> results = items.Select(
            x =>
            new ItemSummaryViewModel
                {
                    ItemId = x.ItemId,
                    Title = x.Title + " " + x.Created.ToString("ddd d MMM HH:mm")
                }).ToList();

そのリストをビューモデルに入れます。

于 2013-03-08T15:10:23.693 に答える
0

質問の「ベストプラクティス」の部分に答えるには:

(アーキテクチャ的に) より効率的な方法は、Unit of Work とリポジトリ パターンを使用することです。こうすることで、ビューをデータ ソースから切り離し、再利用性、テスト性、読みやすさを向上させ、他の "より多く" のものと合わせて保守しやすくします。

この記事は非常にグラフィカルであり、コントローラーからデータベースへのアクセスを分離する必要がある理由を実感できます。

より冗長な方法で変換する方法の技術的な部分に答えるには

AutoMapperと呼ばれるものを使用します。これを使用すると、提示したループの代わりに複雑な変換が次のようになります。

public ActionResult Index()
{
  var dbList = db.Items.ToList();
  var vmList = Mapper.Map<List<Item>, List<ItemSummaryViewModel>>(dbList);
  return View(vmList);
}

また、この初期化を App_Start 構成 (MVC 4 の場合) または Global.asax.cs ファイルのどこかに配置する必要があります。

Mapper.CreateMap<ListOfItems , ItemSummaryViewModelList>();
Mapper.AssertConfigurationIsValid();

AutoMapper を使用する理由とその使用方法について詳しくは、AutoMapper: Getting Started を参照してください。

お役に立てれば!

于 2013-03-08T15:01:03.920 に答える