DBContext和存储库模式运行缓慢

时间:2019-01-08 14:22:27

标签: c# design-patterns asp.net-core

在我的解决方案中,有两个项目:一个名为“ Infrastructure”的.net核心类库和一个名为“ Admin”的.net核心Web应用程序(mvc)。 在“基础结构”中,我实现了Application DBContext的存储库模式,例如:

?

接口:

public partial class ApplicationDbContext : DbContext
{
   ....
}

通用:

public interface IGenericRepository<T> where T : class
{
    T Add(T t);
    ....
}

public interface ICustomersRepository : IGenericRepository<Customers>
{
    Customers GetCustomerByCompanyCode(string companyCode);
    void InsertOrUpdate(Customers toSync);
}

特定:

public class GenericRepository<T> : IGenericRepository<T>, where T : class
{
    protected ApplicationDbContext _context;

    public GenericRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    public virtual T Add(T t)
    {
        _context.Set<T>().Add(t);
        _context.SaveChanges();
        return t;
    }

    ....
}

在Web应用程序中: -Startup.cs

public class CustomersRepository : GenericRepository<Customers>, ICustomersRepository
{
    public CustomersRepository(ApplicationDbContext context) : base(context)
    {
    }
    ....
}

-CustomersController.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))); 
    ....
    services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
    services.AddScoped<ICustomersRepository, CustomersRepository>();
    ....
}

它起作用但非常缓慢:几个小时内插入300.000。如果我不使用存储库模式,而是尝试直接插入调用ApplicationDBContext,例如:

private readonly ICustomersRepository rep;

public CustomersController(ICustomersRepository rep, ....)
{
    this.rep = rep;
    ....    
}

public async Task DoImport()
{
    ....
    rep.InsertOrUpdate(mapper.Map<Customers>(item.Result));
    ....
}

工作时间是:6分钟内插入300.000。

为什么会这样?存储库模式是在.net核心项目中分隔数据访问层的最佳选择吗?还有其他解决方案吗? 提前Tnx。

1 个答案:

答案 0 :(得分:0)

实体框架和存储库模式对于诸如交互式程序的单个记录操作非常有用,在交互式程序中,用户可以创建记录,编辑字段,添加链接的记录等。

如果您想在没有用户交互的情况下导入任意数量的记录,那么EF和存储库模式都会增加很多额外的开销,它们是无用的。 EF会针对每次更改来回访问数据库。因此,如果添加300K记录,那么将有300K往返。太疯狂了

您需要的是名为BULK INSERT的功能。

请参考SqlBulkCopy类以在您的代码中进行此操作。

每个数据库都有自己的工具来执行此操作,因此您需要阅读数据库手册,但是该工具非常快。如果您可以为数据库使用特定工具,那么300K条记录应该在几秒钟之内,而不是几分钟。