ASP。 NET MVC:将实体映射到视图模型

时间:2010-02-15 23:05:33

标签: asp.net-mvc design-patterns methodology automapper

我正在尝试通过使用视图模型来清理ASP.NET MVC项目中的操作方法。目前,我的视图模型包含可能与其他实体有关系的实体。例如,ContactViewModel类可能有一个Contact,它可能有一个Address,这两个都是独立的实体。要查询Contact对象列表,我可能会执行以下操作。

IList<Contact> contacts;

using (IContactRepository repository = new ContactRepository())
{
    contacts = repository.Fetch().ToList();
}

EditContactViewModel vm = new EditContactViewModel(contacts);

return View(vm);

这种方法带来了一些问题。例如,在using语句中查询存储库。到视图呈现时,上下文已超出范围,使视图无法查询与联系人关联的地址。我可以启用急切加载,但我宁愿不这样做。此外,我不喜欢实体模型已经渗透到我的视野中(我觉得我的视图知道联系人和地址之间的关系是一个坏主意,但我可以不同意我的意见。)

我考虑过创建一个包含Contact和Address实体属性的fattened类。然后我可以将Contact和Address实体投影到我新的扁平对象中。我对这种方法的一个担忧是我的动作方法可能会有点忙碌而我认为 AutoMapper能够将两个或多个对象映射到一个类型中。

克服我的担忧是什么技术首选?

2 个答案:

答案 0 :(得分:3)

Automapper适合您的情况。你拥有的是一个对象图,一个东西有更多的东西,Automapper处理得很好。

答案 1 :(得分:1)

按顺序解决这些问题......

首先,如果您担心使用using语句和存储库(我不知道它是LINQ-to-SQL还是LINQ-to-Entities,但它没关系),我会建议你do在Controller上实现IDisposable,然后将存储库存储在模型或控制器中的字段中,或者在视图中可以访问它的位置(如果需要,如果模型知道它,对象是“活着的”然后你只需要在控制器的生命周期中保持它。)

然后,当请求完成时,调用控制器上的Dispose方法,您可以在那里处置存储库。

就个人而言,我的基本控制器类上有一个方法,如下所示:

protected T AddDisposable<T>(T disposable) where T : class, IDisposable
{
    // Error checking.
    if (disposable == null) throw new ArgumentNullException("disposable");

    // Add to list
    ...
}

基本上,它允许您存储IDisposable实现,然后在控制器的IDisposable实现中,它遍历列表,处理所有内容。

关于地址在实体模型上的曝光,我个人并不认为这是一个流血问题。地址是联系人(IMO)组成的一部分,因此将其包含在那里是错误的。

但是,如果您不想在那里,我不同意,因为您希望一次只关注一个控制器中的一种类型,等等。

为此,您需要创建数据传输对象,它基本上映射在视图模型中公开的类型与实体模型之间。