有没有更有效的方法来查询数据并作为视图模型列表传递给视图?

时间:2013-03-08 14:56:16

标签: asp.net-mvc list viewmodel

我有一个 Item 模型映射到DB,如下所示:

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<项目> 并返回列表< ItemSummaryViewModels> 如下:

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

最后,我们使用控制器将列表传递到View中,如下所示:

    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. 要将数据库模型列表()转换为可显示的视图模型列表( ItemSummaryViewModels ),我们当前会遍历列表中的每个项目并单独转换它们。有更有效的方法吗?

  3. 基本上我们查询数据库并将数据分配给ViewModel以显示为列表。我情不自禁地觉得自己“绕过房子”,并且可能会有更高效或“最佳实践方式”。

    有更好的方法吗?

    由于

3 个答案:

答案 0 :(得分: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();

将该列表放在视图模型中。

答案 1 :(得分:1)

关于效率,我不会担心,直到你发现最简单的实施解决方案在实践中过于缓慢。让它先工作,然后只在实际需要时进行优化。显然,在您给出的示例中,有机会只查询和转换视图所需的Items子集(可能是全部,但也许您正在分页?)

在结构上,我认为学术和专业正确的答案是让一组对象代表你的数据库实体,第二组代表“域”或业务对象,第三组代表所有的MVC模型。但是,根据具体情况,可以简化:

  1. 如果业务对象和数据库实体之间存在非常接近的映射,并且数据库不太可能发生显着变化,那么两者都可以有一个类。

  2. 如果您有一组非常简单的视图可以非常干净地映射到您的业务对象,那么您可以使用业务对象作为模型。除非您的观点除了将原始业务对象放到网页上之外什么都不做,我认为您的模型通常需要比当前示例更复杂。

  3. 对于那个特定情况,我同意@CorrugatedAir并说你可以使用普通的List而不是创建自己的List类,如果想要更简单,你可以使用List并跳过创建ItemSummaryViewModel类

    但是尝试在整个应用程序中保持一致 - 所以如果你发现数据库实体不能用作业务对象的情况,那么最好在所有实例中都有一个单独的集合,并在它们之间有映射器。 / p>

答案 2 :(得分:0)

要回答问题的“最佳做法”部分

更有效的方式(架构上)将使用Unit of Work and the repository patterns。这样,您就可以将您的视图与数据源分离,使其更具可重用性,更可测试性,更易读,因此可以与其他“更多”一起进行维护。

这篇文章非常具有图形性,让您真实地了解为什么需要从控制器中拆除数据库访问权。

要回答如何以不那么冗长的方式对其进行转换的技术部分

我会使用名为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

希望这有帮助!