.net 在WCF服务库中处理DBContext

.net 在WCF服务库中处理DBContext,.net,entity-framework,wcf,dbcontext,.net,Entity Framework,Wcf,Dbcontext,我需要在ASP.NET网站上点击一个按钮即可处理大量数据(500K+记录中的CRUD:) 我考虑过使用带有EntityFramework6的WCF服务库来实现这一点。 只有一个edmx,所以我猜只有一个“上下文” 这是我的自动取款机: public interface IBaseRepository<T> : IDisposable { void Insert(T entity); void BulkInsert(IEnumerable<T> entiti

我需要在ASP.NET网站上点击一个按钮即可处理大量数据(500K+记录中的CRUD:) 我考虑过使用带有EntityFramework6的WCF服务库来实现这一点。 只有一个edmx,所以我猜只有一个“上下文”

这是我的自动取款机:

public interface IBaseRepository<T> : IDisposable
{
    void Insert(T entity);
    void BulkInsert(IEnumerable<T> entities);
    void Delete(T entity);
    IQueryable<T> GetAll();
}

public class BaseRepository<T> : IBaseRepository<T> where T : class
{
    protected DbContext _context;
    public BaseRepository(DbContext dataContext)
    {
        _context = dataContext;
    }
    public BaseRepository()
    {
        _context = new MyDBContext();
    }
    public void Insert(T entity){/*CODE*/}
    public void Delete(T entity){/*CODE*/}
    public IQueryable<T> GetAll(){/*CODE*/}
    public void Dispose(){ this.Dispose(); }
}

public interface IProductRepository
{
    IQueryable<Product> GetAllProducts();
}

public class ProductRepository : BaseRepository<Product>, IProductRepository
{
    ProductRepository()
        : base()
    {}

    ProductRepository(DbContext dataContext)
        : base(dataContext)
    {}

    public IQueryable<Product> GetAllProducts()
    {
        return base.GetAll();
    }
}
公共接口IBaseRepository:IDisposable
{
无效插入(T实体);
无效批量插入(IEnumerable实体);
无效删除(T实体);
IQueryable GetAll();
}
公共类BaseRepository:IBaseRepository,其中T:class
{
受保护的DbContext\u context;
公共BaseRepository(DbContext dataContext)
{
_上下文=数据上下文;
}
公共基本存储库()
{
_context=新的MyDBContext();
}
公共无效插入(T实体){/*代码*/}
公共无效删除(T实体){/*代码*/}
公共IQueryable GetAll(){/*代码*/}
public void Dispose(){this.Dispose();}
}
公共接口存储库
{
IQueryable GetAllProducts();
}
公共类ProductRepository:BaseRepository、IPProductRepository
{
ProductRepository()
:base()
{}
ProductRepository(DbContext dataContext)
:base(dataContext)
{}
公共IQueryable GetAllProducts()
{
返回base.GetAll();
}
}
最后的代码将对每个实体重复(每个实体都有一个存储库)

我想知道应该在哪里创建DBContext,应该将它交给每个存储库中的构造函数,还是让BaseRepository构造函数完成它的工作? 如果我将它交给每个存储库,是否意味着我必须在BLL中创建它?我不想这样:\

编辑:

我正在做一些这方面的研究,但我从未使用过依赖注入框架。。所以我不知道如何开始:\


我不确定我是否理解@MattSanders的意思。我知道我应该为上层(控制器)使用Unity之类的依赖注入,但是我应该在哪里创建DBContext呢?我应该使用存储库的空构造函数(这意味着我将为每个存储库提供一个上下文),还是应该将它作为参数传递给每个构造函数(这样我可以在所有存储库中使用相同的上下文)?

如果您的代码依赖于类型化存储库的特定实例,那么在构造函数中接受dbContext以传递给基类构造函数以实现可测试性可能是有价值的

在下面的示例中,如果您只想测试控制器功能,您可以选择提供模拟存储库(使用模拟的数据库集或内存实例模拟上下文,如由Effort提供的)

这肯定不是唯一的答案,但我想与大家分享一下,如果dbContext的依赖关系是在基类构造函数中处理的,而不是公开的,那么我所看到的可测试性的局限性


编辑:以下是指向上述工作的链接:


编辑:

如果我将它交给每个存储库,是否意味着我必须创建它 在BLL里


我一直在使用一个带有IoC容器的工厂来检索我的存储库实例及其所有依赖项,如果您不使用DI框架,它可以帮助处理这些类型的场景。

我建议将依赖项注入到存储库中。在web和堆栈溢出上详细讨论了存储库。;如果您想快速写入500k记录,EF不是一个好办法。特别是,不要像“Insert”方法名称建议的那样为每次写入调用SaveChanges。@usr我同意这一点,并且我通常还会在IRepository上添加一个BulkInsert方法,该方法的实现将使用SqlBulkInsert。在EF 6.1中,有一个公共映射api,可以与.SqlQuery()结合使用,以通过自定义解决方案解决这些类型的问题。我将取消无参数构造函数,只让带有参数的构造函数在创建对象时强制传递它。DI框架也会与多个构造函数混淆,并使用参数最少的构造函数。我建议您更多地了解DI,因为它可能会帮助您理解为什么要这样做,而不仅仅是这样做。此外,如果您已经或正在考虑使用pluralsight订阅,还有一个关于ef和存储库模式的非常好的教程:
public class ProductController
{
    private readonly ProductRepository _productRepository;

    public ProductController (ProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public void BuyProduct(int id)
    {
        // Example of something to do
    }
}