MVC3 - EF4:所有存储库和ViewModel的一个DbContext - UnitOfWork?

时间:2011-12-19 19:37:59

标签: asp.net-mvc-3 entity-framework-4.1 unit-of-work

我完全卡住了。

  • 我有两个控制器:"客户"和"地址"。两者都有字段CustomerRepository和AddressRepository。

  • 有两个ViewModel:CustomerViewModel和AddressViewModel。它们还具有CustomerRepository和AddressRepository字段。 (还有一个无参数构造函数,因为它们是编辑和创建方法中的参数)

  • 存储库本身具有来自我的实体的DbContext对象。

现在我遇到了一个接一个的问题。我想我应该只有一个DbContext与我的所有类共享(Repositories和ViewModels)。我认为UnitOfWork是解决方案。但我不知道如何使用它。

我目前尝试在控制器构造函数中创建一个DbContext,并将其传递给需要它的每个对象。但即使这样也行不通。

如果需要代码,我会发布。

3 个答案:

答案 0 :(得分:4)

要了解的事情:

1。工作单元

工作单元不一定是IUnitOfWork的某种实施方式。它只是一种可能以多种方式应用的模式。首先,最重要的是 - 在实际使用它之前你应该理解它是什么,并使周围的事情过于复杂。此外,EF Code-First DbContext API的DbContext 一种Unit of Work模式。您的IDbSet<>是您的存储库。不要试图从你的ORM中抽象出来,从最简单的事情开始。

2。 DbContext注入

首先,只需使用构造函数注入将DbContext注入Controller。不要忘记设置所选的IoC容器并连接MVC的DependencyResolver。您的控制器可能看起来像(示例还包含AutoMapper用法示例,请参阅有关ViewModels的下一点):

public CustomerController : Controller
{
    public CustomerController(MyDbContext data, IMappingEngine mapper)
    {
        Data = data;
        Mapper = mapper;
    }

    public MyDbContext Data { get; set; }

    public IMappingEngine Mapper { get; set; }

    // Other controller code
}

3。查看模型

这又是一个易于实现的模式 - 只需使用CustomerViewModel并使用AutoMapper即可轻松将Customer转换为CustomerViewModel,以便您可以这样做:

public ActionResult Details(int id)
{
    var customer = Data.Customers.FirstOrDefault(c => c.Id == id);

    if (customer == null)
        return new HttpNotFoundResult();

    return View(Mapper.Map<CustomerViewModel>(customer));
}

您可以询问AutoMapper的网站,了解如何连接并使其运行。 请注意,您没有直接从DbContext获取ViewModel。您获得一个“实体”,然后转换为适当的视图模型。

希望这有帮助!

答案 1 :(得分:2)

您的ViewModel不应该引用DbContext或存储库。 ViewModels应该是非常愚蠢的。控制器(或控制器调用的服务)的工作是使用View所需的数据填充ViewModel。

工作单位是一个很好的模式,你应该使用它...但是patern不能解决你的问题。您的问题是您的视图对数据模型的了解太多。

答案 2 :(得分:0)

我目前正在执行以下操作: 一个注入IUnitOfWork使用unity注入我的控制器。

IUnitOfWork实现了IContext。

IContext包含IDbSet Customers和IDbSet IContext的具体实现实现了DbContext。

我的控制器引用服务,该服务使用IUnitOfWork。 如果您使用存储库,那么只需使用注入控制器的单个IContext(或IUnitOfWork,它很容易添加到顶部)

这样我在请求的每个生命周期中都有一个上下文,然后它被处理掉了。如果你想要更多代码,请告诉我,我会看到我可以在这里发布的内容。