C# 实体框架7中奇怪的缓存问题

C# 实体框架7中奇怪的缓存问题,c#,asp.net,.net,asp.net-mvc,entity-framework,C#,Asp.net,.net,Asp.net Mvc,Entity Framework,我遇到了一些非常具体的问题,我想知道是否有人遇到过同样的问题 我的SQL查询(在存储过程中)很简单,我对其进行了一些简化,但: BEGIN SELECT DISTINCT [ANU].[OldUserId] AS [ID] ,[ANU].[Email] FROM [dbo].[AspNetUsers] AS [ANU] INNER JOIN [dbo].

我遇到了一些非常具体的问题,我想知道是否有人遇到过同样的问题

我的SQL查询(在存储过程中)很简单,我对其进行了一些简化,但:

BEGIN
        SELECT DISTINCT
            [ANU].[OldUserId] AS [ID]
            ,[ANU].[Email]
        FROM
            [dbo].[AspNetUsers] AS [ANU]
        INNER JOIN
            [dbo].[User] AS [U]
        ON
            [U].[ID] = [ANU].[OldUserId]
    END
非常简单,直接通过SQL Management Studio运行时,SP也很好

但是,我通过实体框架运行它,如下所示:

 [ResponseCache(Duration = 0)] // used this out of desperation
 public List<DriverDTO> GetByOrganisation(int organisationId, bool isManager)
 {
      return _context.Set<DriverDTO>().FromSql("dbo.New_User_List @OrganisationId = {0}, @IsManager = {1}", organisationId, isManager).ToList();
 }
它运行并返回结果,很好。但是,这些结果正在被缓存。在第一次调用后对SP的每次调用都会返回相同的结果,即使我更新了记录也是如此。因此,假设我编辑了一个用户记录并更改了电子邮件-最初获取的电子邮件将始终被带回


同样,通过SQL管理器运行SP会返回正确的结果,但我的C#/EF端没有。我脑子里唯一合乎逻辑的事情是,某种东西不知何故被藏在引擎盖下,我迫切需要四处走动

加载的实体缓存在
DbContext
中(在每个
DbSet
Local
集合中)

有几种选择:

  • 使用
    AsNoTracking
    进行查询:

    return _context.Set<DriverDTO>()
               .AsNoTracking()
               .FromSql("dbo.New_User_List @OrganisationId = {0}, @IsManager = {1}", organisationId, isManager)
               .ToList();
    
    请注意,与人们的想法相反,您不能使用
    \u context.Set().Local.Clear()
    ,因为这会将您的实体标记为已删除(因此如果您
    SaveChanges
    之后,它会将实体从数据库中删除),因此在尝试本地缓存时要小心


  • 除非您需要使用单个
    DbContext
    ,或者将从SP接收到的实体连接到它,否则我会选择#2。否则,我会选择1。为了完整起见,我把#3放在那里,但除非绝对必要,否则我会避免弄乱本地缓存。

    今天你帮了我大忙,谢谢!.AsNoTracking()函数对我来说绝对是一种享受,是我的场景中最简单的方法。我只是希望这也能帮助其他人。@ChrisDixon很高兴它有帮助。作为旁注,
    AsNoTracking
    查询比普通EF查询速度快得多,所需内存不到一半。。。所以我会一直使用它,除非有理由不(基本上,只要你的上下文只用于查询,而不用于更新/删除)明智的建议。每天学习一些新的东西,将大大加快我的系统!
    return _context.Set<DriverDTO>()
               .AsNoTracking()
               .FromSql("dbo.New_User_List @OrganisationId = {0}, @IsManager = {1}", organisationId, isManager)
               .ToList();
    
    _context.Set<DriverDTO>().Local.ToList().ForEach(x=>
    {
       _context.Entry(x).State = EntityState.Detached;
    });