我有一个 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);
}
我的问题是:
这样做有效还是“最佳实践”?
要将数据库模型列表(项)转换为可显示的视图模型列表( ItemSummaryViewModels ),我们当前会遍历列表中的每个项目并单独转换它们。有更有效的方法吗?
基本上我们查询数据库并将数据分配给ViewModel以显示为列表。我情不自禁地觉得自己“绕过房子”,并且可能会有更高效或“最佳实践方式”。
有更好的方法吗?
由于
答案 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模型。但是,根据具体情况,可以简化:
如果业务对象和数据库实体之间存在非常接近的映射,并且数据库不太可能发生显着变化,那么两者都可以有一个类。
如果您有一组非常简单的视图可以非常干净地映射到您的业务对象,那么您可以使用业务对象作为模型。除非您的观点除了将原始业务对象放到网页上之外什么都不做,我认为您的模型通常需要比当前示例更复杂。
对于那个特定情况,我同意@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
希望这有帮助!