MVC5和实体框架多线程

时间:2017-09-18 23:59:04

标签: multithreading entity-framework caching asp.net-mvc-5

我有一个用MVC5和Entity Framework 6编写的应用程序。 当用户登录主页时,我运行查询并获取可供查看的报告摘要。

在某些情况下,当多个用户登录不同的客户端时,一个用户获得了另一个客户端的数据而不是他们的数据。 管理人员当时也记录了它以进行验证,并确认它正在发生。但是当我收到通知的时候,它没有再发生,现在已经很晚了,没有多少用户在工作。

我的家庭控制器使用DI来获取数据库上下文。

 private IDataRepository db = null;
 public HomeController(IDataRepository dbContext)
 {
     this.db = dbContext;
 }

我正在使用Ninject进行依赖注入

public class NinjectDependencyResolver : IDependencyResolver
{
    private IKernel kernel;
    public NinjectDependencyResolver(IKernel kernelParam)
    {
        kernel = kernelParam;
        AddBindings();
    }
    public object GetService(Type serviceType)
    {
        return kernel.TryGet(serviceType);
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        return kernel.GetAll(serviceType);
    }
    private void AddBindings()
    {
        kernel.Bind<IDataRepository>().To<DataRepository>();

    }
}

存储库和dbcontext在单独的库项目中定义

这是从家庭控制器调用摘要的代码

   var summaries = db.reportSummary(client_id, 0, fromDate, toDate, 0, 10); 
    foreach (sp_slct__report_Result s in summaries)
    {
        reports.Add(new ClientReportSummary(s));
    }

方法ReportSummary位于一个单独的类中:

  public class ClientReportSummary
    {
        sp_slct_report_Result summary = null;

        public ClientReportSummary(sp_slct_report_Result summary)
        {
            this.summary = summary;
        }
   }

和DbContext函数

public IEnumerable<sp_slct__report_Result> reportSummary(int clientId, 
   long reportId, DateTime startDate, DateTime endDate, byte minStatus, 
   byte maxStatus)
{
    try
    {
        return sp_slct__report(clientId, reportId, startDate, endDate, 
             minStatus, maxStatus);
    }
    catch (Exception ex)
    {
        Logger.error(ex);
        throw ex;
    }
}

sp_slct__report_Result是一个存储过程。

我不认为DI不是线程安全的,但是实体框架可能正在缓存数据和/或查询并返回错误的东西?

我甚至不确定如何测试这个,有没有办法跟踪并查看在特定时间执行了哪些查询?

任何防止/调试此最佳实践的建议,AsNoTracking()都会修复此问题吗?

提前谢谢

1 个答案:

答案 0 :(得分:0)

看起来您已配置了一些日志记录。您可以通过配置Database属性的日志操作

来记录原始查询
context.Database.Log = s => Logger.info(s);

这适用于映射到EF模型的存储过程。