Asp.net mvc 5 ASP.NET MVC 5中EntityFramework中的底层NullReferenceException问题

Asp.net mvc 5 ASP.NET MVC 5中EntityFramework中的底层NullReferenceException问题,asp.net-mvc-5,entity-framework-6.1,Asp.net Mvc 5,Entity Framework 6.1,专家 我在访问MVC5网站的主页时遇到问题,请查看下面的异常详细信息 MVC 5.2.2 实体框架6.1.1 Visual Studio 2013 System.NullReferenceException: Object reference not set to an instance of an object. at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValu

专家

我在访问MVC5网站的主页时遇到问题,请查看下面的异常详细信息

MVC 5.2.2

实体框架6.1.1

Visual Studio 2013

System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValue(MemberExpression me, Object instance, Object& memberValue)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryEvaluatePath(Expression expression, ConstantExpression& constantExpression)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.EvaluateParameter(Object[] arguments)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassc.<GetResultsAsync>b__a()
at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
代码非常简单,它从当前OwinContext中共享的数据上下文异步查询数据,工作正常,但意外地,由于之前的错误,它失败了

public class TalentsService : ServiceBase
{
    public async Task<List<TalentSummaryViewModel>> GetSlotlightTalents()
    {
        var talents = await DbContext.Talents.Where(t => t.IsSpotlight && IsAuthenticated).ToListAsync();

        return talents.Select(t => WrapModel(t)).ToList();
    }
}

public abstract class ServiceBase
{
    private ApplicationDbContext _dbContext;
    public ApplicationDbContext DbContext
    {
        get
        {
            return _dbContext ?? HttpContext.Current.GetOwinContext().Get<ApplicationDbContext>();
        }
        private set
        {
            _dbContext = value;
        }
    }

    public bool IsAuthenticated
    {
        get
        {
            return HttpContext.Current.Request.IsAuthenticated;
        }
    }
}

多线程相关吗?我无法找出根本原因,请提供任何线索,提前感谢。

感谢Chris Pratt的回复,让我再次检查代码,根本原因是:


HttpContext.Current在我不知道的某些情况下为null,然后对该属性的调用IsAuthenticated失败,因此我必须将IsAuthenticated值存储在局部变量中,现在我可以在使用LoadTest工具启动大量请求时轻松地重设此问题,但是仍然不清楚为什么上下文会意外丢失,可能其他人对此有更多的了解。

在对我的Web API发出第一个HTTP请求后,我遇到了相同的错误,只有在回收IIS应用程序时,该错误才是可复制的。显然,在重新启动IIS后,第一个传入请求通过IQueryable启动数据检索,内联ClientID参数从以下位置提取:

HttpContext.Current.User作为ClaimsPrincipal.Claims以异步方式收集

因此,当I/O操作完成时,HttpRequest上下文不存在。。。 将Http声明值复制到单独的变量中,并在构造IQueryable时使用此变量解决了问题:


var claims=HttpContext.Current.User作为ClaimsPrincipal.claims

这里没有足够的数据来确定问题。简单地说,当您尝试引用运行时计算结果为null的对象实例上的属性或方法时,会出现该异常。例如,如果您从数据库中拉出一个项,但在尝试显示其属性之前未能检查该项是否为null。您需要在代码中找到并标识发生这种情况的位置。@chrispratt感谢您的响应Chris,根据异常,执行数据查询行代码时这是EntityFramework的一个基本问题,从上面的代码中,您认为哪个调用会导致此NullReferenceException错误?我确信作为IsAuthenticated源的http上下文不会为null,因此唯一的机会是从db查询返回的talent对象,但我不敢相信EntityFramework会为我提供一个在db中不存在的null对象。@chrispratt P.S.我在其他不使用async的代码中从未遇到过这种问题,所以我的理解是db上下文或某些操作可能不是线程安全的,当线程初始化db上下文时,会发生另一个调用并读取尚未准备好的数据,所以我只能意外地得到这个错误,但我需要有人再次确认这是否是真的。不,这根本不是真的。实体框架是完全线程安全的,只要您不做一些愚蠢的事情,比如跨多个请求使用相同的上下文实例。我的理解是,绑定到OWIN上下文应该是线程安全的,但归根结底,这并不是一个真正的、功能完整的DI容器。就我个人而言,我会使用一个真正的DI容器,看看这是否足以解决您的问题。@ChrisPratt谢谢Chris,我想我解决了这个问题,您是正确的,HttpContext。在我不知道的某些情况下,Current为null,然后对该属性的调用被验证失败,因此,我必须将IsAuthenticated值存储在局部变量中,现在我可以在使用LoadTest工具启动大量请求时轻松地重新设置此问题,但仍然不清楚为什么上下文会意外丢失,有任何线索吗?虽然此答案无法解决问题,但它确实确认了这是一个问题。我也遇到了同样的问题,在计算表达式时,HttpContext.Current.User.Identity属性中的某些内容为null