我有一个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);
}
我的问题是:
有没有更有效或"最佳实践"的方法来做到这一点?
为了将DB模型列表(Item(转换为可显示视图模型列表(ItemSummaryViewModels。有更有效的方法吗?
从本质上讲,我们查询数据库并将数据分配给ViewModel以显示为列表。我忍不住觉得我有点"绕房子转"了,也许有一种更有效或"最佳实践"的方法可以做到这一点。
有更好的方法吗?
感谢
尝试使用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();
将该列表放入视图模型中。
关于效率,我不会担心,直到您发现最简单的实现解决方案在实践中过于缓慢。先让它发挥作用,然后只在实际需要时进行优化。显然,在您给出的示例中,有机会只查询和转换视图所需的项的子集(可能是全部,但可能您正在分页?(
从结构上讲,我认为学术上和专业上正确的答案是有一组对象来表示数据库实体,第二组对象来代表"域"或业务对象,第三组对象代表所有MVC模型。然而,根据具体情况,这可以简化:
-
如果业务对象和数据库实体之间存在非常紧密的映射,并且数据库不太可能发生重大更改,那么您可以为这两个对象都创建一个类。
-
如果您有一组非常简单的视图,可以非常干净地映射到业务对象上,那么也许您可以使用业务对象作为模型。除非你的视图只把原始的业务对象放在网页上,否则我认为你的模型通常需要比你当前的例子更复杂。
对于这种特定的情况,我同意@CorrugatedAir的观点,并说你可以只使用一个普通的List,而不是创建自己的List类,如果想更简单,你也可以使用List并跳过创建ItemSummaryViewModel类。
但是,请尝试在整个应用程序中保持一致——因此,如果您发现数据库实体不能用作业务对象,那么最好在所有实例中都有一个单独的集合,并在它们之间设置映射器。
要回答问题的"最佳实践"部分:
更有效的方法(从体系结构上(是使用工作单元和存储库模式。通过这种方式,您可以将视图与数据源解耦,使其更可重用、更可测试、更可读,从而与其他"更多"视图一起更易于维护。
这篇文章非常图形化,让您真正感受到为什么需要从控制器中分离数据库访问。
要回答如何以不那么冗长的方式转换它的技术部分,
我会用一个叫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:入门
希望这能有所帮助!