【问题标题】:Navigation property incompletely loaded after eager load急切加载后导航属性未完全加载
【发布时间】:2014-06-16 04:32:41
【问题描述】:

我使用一个类似这样的代码来选择一个大的对象列表,用于只读目的:

using (DBContext db = new MyContextClass())
{
    ... data creation ... 
    db.SaveChanges();
}

using (DBContext db = new MyContextClass())
{
     db.Configuration.LazyLoadingEnabled = false;
     db.Configuration.ProxyCreationEnabled = false;
     db.Configuration.AutoDetectChangesEnabled = false;

     DbQuery data = db.Set(someType)
     foreach (string propertyName op in somePropertieNames)
                data = data.Include(propertyName);

     foreach (object item in data.AsNoTracking())
         ScanNavigatorsOf(item);
}

ScanNavigatorsOf() 中,我阅读了所有导航属性,并注意到foreach 循环产生的第一个对象具有不完整的集合和引用。在程序点击我的ScanNavigatorsOf(...) 方法时,导航属性的填充似乎还没有完成。所有其他对象都具有完整的导航属性。我正在对此进行单元测试,因此我可以确保对象很好地存储在数据库中。

如何等待已加载对象的导航集合和引用完全填充?

就像ObjectContext.ObjectMaterialized Event 中解释的那样,集合似乎没有与 main 对象同时实现,但是我如何知道该过程何时完成?

【问题讨论】:

    标签: c# .net entity-framework entity-framework-6


    【解决方案1】:

    我很确定您正在经历关闭DetectChanges 的副作用。这是 EF 在表面下调用many times 以确保已正确建立跟踪实体之间的所有关联并与原始外键值匹配(这称为关系修复)。您可能有理由将其关闭,但正如 Lerman & Miller 在他们的书 DbContext 中所说:

    确定何时需要调用 DetectChanges 并不是那么简单 可能会出现。 Entity Framework 团队强烈建议您 如果您遇到,请仅切换到手动调用 DetectChanges 性能问题。还建议只选择退出自动 DetectChanges 用于表现不佳的代码部分并重新启用它 一旦相关部分完成执行。

    除此之外,您无需跟踪即可获取对象。现在 EF 在关联方面几乎完全瘫痪了。

    您应该让DetectChanges 完成它的工作,或者在循环中调用它。并启用跟踪,否则更改跟踪器无法修复关联。

     foreach (object item in data)
     {
         db.ChangeTracker.DetectChanges();
         ScanNavigatorsOf(item);
     }
    

    或者在循环运行之前打开AutoDetectChangesEnabled,当在ScanNavigatorsOf中触发DetectChanges的众多方法之一将运行。

    AsNoTracking 中还有另一个问题。关闭更改跟踪的效果是上下文不能用作身份映射,这意味着:它不能确保数据库中的每条记录都会被具体化一次。 p>

    如果您的Includes 中存在1-n-1 关联,例如Order-OrderLine-Product,则不会为每个OrderLine 跟踪一个新的Product 实例,即使已经为其创建了“相同”产品上一个订单行。只要您以只读方式使用数据,这不是一个大问题,但是一旦您将它们附加到上下文(例如用于复制),您就会遇到重复键异常。

    简而言之:当关联很重要时,让更改跟踪器完成其工作并确保及时调用DetectChanges

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多