繁体   English   中英

急切加载后导航属性未完全加载

[英]Navigation property incompletely loaded after eager load

我使用类似于以下代码的代码来选择大量对象,以供只读:

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(...)我的ScanNavigatorsOf(...)方法时,导航属性的填充似乎尚未完成。 所有其他对象都具有完整的导航属性。 我正在对此进行单元测试,因此我可以确保对象正确存储在数据库中。

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

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

首先使用ToList()加载所有数据,然后扫描导航属性:

var queryableData = db.Set(someType).AsNoTracking();
var data = somePropertieNames.Aggregate(queryableData , (current, property) => current.Include(property)).ToList();
foreach (object item in data)
         ScanNavigatorsOf(item);

我很确定您遇到关闭DetectChanges 这是EF在表面之下进行的多次调用,以确保已正确建立被跟踪实体之间的所有关联并与原始外键值匹配(这称为“ 关系修正” )。 您可能有理由将其关闭,但正如Lerman&Miller在他们的书DbContext中所说

确定何时需要调用DetectChanges并不像看起来那么琐碎。 实体框架团队强烈建议您仅在遇到性能问题时才转换为手动调用DetectChanges。 还建议仅对性能不佳的代码部分选择不使用自动DetectChanges,并在相关部分完成执行后重新启用它。

最重要的是,您无需跟踪即可获取对象。 现在,在关联方面,EF几乎完全瘫痪了。

您应该让DetectChanges进行工作,或者在循环中调用它。 并启用跟踪功能,否则更改跟踪程序将无法修复关联。

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

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

但是AsNoTracking还有另一个AsNoTracking 关闭变更跟踪的作用是,上下文不能用作身份映射 ,这意味着:它不能确保数据库中的每个记录都会准确地实现一次。

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

简而言之:当关联很重要时,让变更跟踪器执行其工作,并确保DetectChanges调用DetectChanges

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM