1

我应该如何在 MVC 控制器中实例化数据上下文(实体 fw):

  • a) 作为类中的属性
  • b) 作为类中的一个字段
  • c) 作为 Action 中的变量
  • d) 使用 Repository 模式抽象出你的 DbContext

在 WebForms 中我会使用 c),因为 b) 会跨事件维护 db 对象状态,这通常不是我想要的。

我实际上从未使用过a)。

4

5 回答 5

2

您可能应该使用repository patternwithdependency injection
通过构造函数传入上下文,
并且使用它您将不得不使用像Unity这样的收费来在constructor

于 2012-07-10T14:08:26.133 回答
0

我想首先说我 100% 同意@jrummell,因为 DbContext 应该被实例化。但是,如果您不打算这样做,我将使用私有只读字段并提供两个构造函数:

public MyController() : this(new DbContext()) { }

public MyController(DbContext context)
{
   this._dbContext = context;
}

这样您仍然可以注入 DbContext 进行测试。

于 2012-07-10T14:09:42.030 回答
0

有一个私有变量,它是您的存储库接口的对象,并在您的构造函数中实例化它。您现在可以在所有操作方法中使用它

public class ItemsController : Controller
{
    private IRepositary repo;

    public ItemsController()
    {
        repo = new Repositary(new YourDBContext());
    }
    public ActionResult Edit(int id)
    {
      var item=repo.GetItemById(id);
      //if needed, map to your view model and return that to the view
     //  instead of model object to the view
      return View(item);
    }
}
于 2012-07-10T14:09:45.493 回答
0

推荐的方法是使用与持久性无关的数据访问模式,例如存储库模式。基本思想是创建特定于控制器的接口,以抽象出您的数据访问。

public interface ICatalogRepository : IRepository
{
  Category GetCategory(int id);
  Product GetProduct(int id);

  void Add(Product product);

  IEnumerable<Category> Categories { get; }
  IEnumerable<Supplier> Suppliers { get; }
}

public class CatalogRepository : ICatalogRepository
{
  private YourDbContext _db;

  public CatalogRepository(YourDbContext db)
  {
     _db = db;
  }

  public Category GetCategory(int id)
  {
     return _db.Categories.Find(id);
  }
  /* ... */
}

然后你会在你的控制器中使用一个实例ICatalogRepository——它不会有任何实体框架的知识。有关完整示例,请参阅在 ASP.NET MVC 中使用按请求工作单元模式。

于 2012-07-10T14:10:10.530 回答
0

除非这是一个非常小的应用程序或只有少数用户;或者应用程序的生命周期很短,我永远不会将任何数据访问“类似”的代码放在 UI 层中。您刚刚做出了会影响应用程序的可维护性和可测试性的设计决策。

我喜欢使用带有依赖注入的存储库模式的想法 - 这已被证明非常有效。事实上,我目前使用的应用程序每月处理超过 110 亿个 Web 请求,使用这种模式针对 7 个不同的 MySQL 数据库实例。

另一个建议,在 UI 下实现一个服务/业务层。这一层的职责之一是为业务处理和数据库事务提供 API。我通常在业务层实现存储库,但它为实际的数据库特定事务引用并使用数据访问层组件。通过这种方式,您可以在业务层中抽象出数据访问——这是一件好事,因为长期存在的应用程序会在数据访问中发生许多变化。有了这个很好的抽象,您可以使用实体框架或任何其他数据库技术,如 NoSQL。此外,使用 DI,接口/抽象类允许您将“存储库”的实例注入业务组件 - 这肯定会提高应用程序的可测试性:

希望这可以帮助。

于 2012-07-10T14:21:02.037 回答