【问题标题】:Unit of Work, Entity Framework DBContext Scope工作单元,实体框架 DBContext 范围
【发布时间】:2013-01-11 10:59:27
【问题描述】:

我在 EF 中遇到了一些问题,正在寻找解决这个问题的最佳实践:

public void TestEntityFramework_UOWImplementation()
{
    using (UnitOfWorkInventory uow = new UnitOfWorkInventory())
    {
        IMaterialRepository repos = new MaterialRepository(uow);

        Material mat = GetMaterial("Mikes Material", 1);

        mat.CostPrice = 20;

        repos.InsertOrUpdate(mat);

        uow.Commit();
    }
}

private Material GetMaterial(string sku, int clientId)
{
    IMaterialRepository repos = new MaterialRepository(new UnitOfWorkInventory();

    return repos.Find(sku, clientId);

}

在 TestEntityFramework_UOWImplementation() 方法中,它很好,我调用为我的工作单元创建一个范围......并在其中创建一个存储库。

但是当我想 getMaterials() 如下时.. 我无法访问工作单元或存储库,除非我实际上将它作为参数传递!这显然不是特别好。

人们如何解决这个问题??

提前致谢!

尼尔

【问题讨论】:

  • 不应该GetMaterialMaterialRepository 类中的实例方法吗?
  • 这是一个好点! :) 但是说在某些情况下你想做一个 Where() .. 我想这些也会在回购中。谢谢!现在我看到它写得很明显:)
  • 实际上,假设需要几个 repo 查询。您认为不会出现在回购之外进行查询的情况吗?或者说我有一些名为 CalculateMaterialPrices() 的方法,它需要一个材料列表来计算。你会在 TestEntityFramework_UOWImplementation() 方法或 CalculateMaterialPrices() 方法中调用 repo GetMaterials() 方法,如果是后者,你将如何访问 repo?还是我不是在正确的轨道上!
  • 现在更多的框架期望使用IQueryable<T> - 我正在考虑诸如Web API之类的东西 - 所以向每个只返回一个的存储库添加一个方法会很有用。这也满足了您所描述的用例,您希望在存储库之外指定查询。这是否会破坏封装是有争议的,但它可以完成工作!
  • 它是一种解决方法,但绝对不是一个好的解决方案。有没有办法解决这个问题?

标签: entity-framework repository-pattern unit-of-work


【解决方案1】:

在您的实施中,您将无法访问这样的工作单元。我所做的是使用 IoC 容器和依赖注入来处理它。我有一个 WCF 服务,它使用工作单元和针对 EF5 的存储库模式。

您可以阅读有关存储库模式、工作单元和 EF here 的更多信息,但基本上我所做的是在我的服务类的构造函数中注入工作单元,如下所示:

    private readonly IUnitOfWork uow;

    public LoanService(IUnitOfWork unitOfWork)
    {
        uow = unitOfWork;
    }

然后我可以在服务的任何地方在我的存储库中使用 uow.WhateverMethod。我使用Ninject 来处理IUnitOfWork 的注入。希望对你有帮助。

【讨论】:

    【解决方案2】:

    如果有人正在寻找解决此问题的方法,我做了一些不同的事情。

    我使用依赖注入框架 (StructureMap) 来处理所有 DI,所以每次我实例化一个存储库时,它都会从 StructureMap 的服务定位器中检索 DBContext。我还将 dbcontext 范围设置为来自网络服务器的请求期间。

    这里的优点是每次我检索或注入 DBContext 时,它都会在请求期间检索相同的上下文,这意味着我可以在多个方法和类中使用它!我将接口类型作为通用参数传递给构造函数,这意味着我可以将 repo 指向不同的上下文。在有大量 dbcontexts 的应用程序中很有帮助。

    回购构造函数例如:

    public class PurchaseOrderRepository<TDbContext> : GenericRepository<PurchaseOrder>, IPurchaseOrderRepository<TDbContext> where TDbContext : DbContext
    {
    
            public PurchaseOrderRepository()
                : base((TDbContext)ObjectFactory.GetInstance<TDbContext>())
            {
            }
    }   
    

    用法:

     //resolves the request scope InventoryContext... 
    var pRepos = new PurchaseOrderRepository<IInventoryContext>();
    

    结构映射依赖如下:

        For<IInventoryContext>().HttpContextScoped().Use<InventoryContext>();
    

    【讨论】:

    • 我对意见感兴趣!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2012-02-02
    相关资源
    最近更新 更多