1

我有一个项目模型映射到数据库,如下所示:

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 ) 列表,我们目前遍历列表中的每个项目并单独转换它们。有没有更有效的方法来做到这一点?

本质上,我们正在查询数据库并将数据分配给 ViewModel 以显示为列表。我情不自禁地觉得我在“四处走动”,并且可能有一种更有效或“最佳实践”的方式来做到这一点。

有没有更好的办法?

谢谢

4

3 回答 3

1

尝试使用 LINQ 选择:

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 回答
1

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

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

  1. 如果业务对象和数据库实体之间存在非常紧密的映射,并且数据库不太可能发生重大变化,那么您可以为两者使用一个类。

  2. 如果您有一组非常简单的视图,可以非常干净地映射到您的业务对象,那么也许您可以使用业务对象作为您的模型。除非您的视图只是将原始业务对象添加到网页上,否则我认为您的模型通常需要比您当前的示例更复杂。

对于这种特定情况,我同意@CorrugatedAir 并说您可以只使用普通 List 而不是创建自己的 List 类,如果想要更简单,您也可以使用 List 并跳过创建 ItemSummaryViewModel 类。

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

于 2013-03-08T16:04:41.293 回答
0

要回答问题的“最佳实践”部分

更有效的方法(架构上)将是使用工作单元和存储库模式。通过这种方式,您可以将视图与数据源分离,使其更可重用、更可测试、更易读,因此与其他“更多”一起更易于维护。

这篇文章非常图形化,让您真正了解为什么需要从控制器中分离数据库访问。

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

我会使用一种叫做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:入门

希望这可以帮助!

于 2013-03-08T15:01:03.920 回答