【问题标题】:Why navigation propery sometimes return null?为什么导航属性有时会返回 null?
【发布时间】:2015-03-28 12:25:22
【问题描述】:

我有两个模型

public class Indicator
{
    public long IndicatorID { get; set; }
    public string Name { get; set; }
    public int MaxPoint { get; set; }
    public string Comment { get; set; }
    public DateTime DateChanged { get; set; }
    public DateTime DateCreated { get; set; }

    public virtual IList<CalculationType> CalculationTypes { get; set; }
}

public class CalculationType
{
    public long CalculationTypeID { get; set; }
    public string UnitName { get; set; }
    public int Point { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateChanged { get; set; }

    public virtual Indicator Indicator { get; set; }
}

我有数据库工厂

public class DatabaseFactory
{
    private StankinQuestionnaireEntities dataContext;
    public StankinQuestionnaireEntities Get()
    {
        return dataContext ?? (dataContext = new StankinQuestionnaireEntities());
    }
}

以及引用databaseFactory的属性

protected StankinQuestionnaireEntities DataContext
{
    get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}

我使用 Autofac 和注册数据库工厂

builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerRequest();

在我的存储库中,我尝试通过两种方式从导航属性中获取数据

第一行工作正常(CalculationType 包含一个元素)

但第二行在属性 CalculationType 上返回 null

为什么?

更新 我发现如果删除“.InstancePerRequest()”行,一切正常。但我不适合这个。

UPDATE2由于某种原因,没有创建代理类

【问题讨论】:

  • 在第一种情况下,您有一个代理(查看其运行时类型)。在第二种情况下,您有基本模型类型。您期望的导航属性的行为仅适用于代理,因为代理是您的基本模型类型的子类型,它覆盖您的导航属性以提供简单和延迟加载。如果没有代理,框架就没有机会覆盖导航属性并为您提供所需的行为。
  • @TheodorosChatzigiannakis 但为什么 ef 没有创建代理类? ProxyEnable 设置为真savepic.net/6498011.png

标签: c# asp.net asp.net-mvc entity-framework autofac


【解决方案1】:

您的数据库上下文肯定有不同的 ProxyCreationEnabled 属性值。

如果您在屏幕截图中查看所选实体的类型,您会发现第一个的类型为 System.Data.Entity.DynamicProxies.Indicator_E...,第二个的类型为 StankinQuestionnaire.Model.Indicator。

这意味着 ProxyCreationEnabled 对于第一个数据库上下文为 true,而对于第二个数据库上下文该属性为 false。因此,延迟加载在第二种情况下不起作用。

尝试在你的项目中搜索 ProxyCreationEnabled 设置的位置,可能你有不止一个地方。

【讨论】:

  • 但是是的,由于某种原因,没有创建代理类。
  • 好吧,我已经下载了你的项目。我从你的另一个问题中得到一个链接。然后我将通过 Id 查询指标的代码放在CalculationTypeRepositoryUpdateIndicator 方法中,并从Home 控制器中调用它。没有问题。为这两个对象创建代理。 Screenshot。所以,我仍然认为您在新代码中的某处禁用了代理创建。
  • 非常感谢!您试图帮助我找到问题。我调用了附加到空模型属性savepic.net/6530791.png 的方法
【解决方案2】:

试试这个:

DbContext.Configuration.ProxyCreationEnabled = true;    
DbContext.Configuration.LazyLoadingEnabled = true;  

如果 DbContext.Configuration.ProxyCreationEnabled 设置为 false,除非在父对象上调用 Include 方法,否则 DbContext 将不会为某些父对象加载子对象。将 DbContext.Configuration.LazyLoadingEnabled 设置为 true 或 false 不会对其行为产生影响。

如果 DbContext.Configuration.ProxyCreationEnabled 设置为 true,子对象将被自动加载,并且 DbContext.Configuration.LazyLoadingEnabled 值将控制何时加载子对象。

我认为这篇文章与此相同:Why EF navigation property return null?

【讨论】:

  • 我问过这个stackoverflow.com/questions/29272581/… :) 我发现如果删除“.InstancePerRequest()”行,一切正常。但我不适合这个。
  • @kriper 看起来上下文在您处于调试视图时已被释放。也许你可以覆盖上下文的Dispose 方法并在in 中设置一个断点。
  • @GertArnold 在处置中,导航属性也为空savepic.net/6536837.png
  • @GertArnold 最有趣的一点是,一些导航属性可以正常工作,但该属性 (CalculationTypes) 仅在手动加载或手动创建上下文后绑定。
【解决方案3】:

我有同样的问题,第一次加载页面时它工作正常, 当我刷新页面时,我得到空引用异常。就我而言,我使用的是 Task

System.Threading.Tasks.Task.Run(() =>
             {

});

此任务使用 Dbcontext 插入一条记录。我只是删除任务,一切都开始正常工作。

【讨论】:

    猜你喜欢
    • 2015-05-30
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多