2011-04-30 72 views
2

我有1:n关系中的两个实体:链接,类别。在第一次,我得到所有类别和链接,并把它们列出。接下来我手动填写每个类别的链接,但是category.Links.Add(link)连接到数据库并再次获取链接,并导致结果中的双重数据。我知道这个动作是因为延迟加载。延迟加载是真实的,我不想禁用它。如何在不连接到db的情况下手动填充每个类别的链接? 请不要提供Eager loading或disabeling懒惰负载。在实体框架中延迟加载的问题

 var categories = categoryRepository.GetCategories().ToList(); 
     var allLinks = linkRepository.GetLinks().ToList(); 

     foreach (var category in categories) 
     { 
      var links = allLinks.Where(l => l.CategoryID == category.CategoryID); 

      foreach (var link in links) 
      { 
       category.Links.Add(link); 
      } 
     } 
+0

你能解释为什么你想要这个,你为什么要在同一时间使用延迟加载? – 2011-04-30 13:03:50

+0

它只是一个样本。我使用这个解决方案来提高性能。我不想在同一时间使用延迟加载时执行此操作。我想在其他查询中使用延迟加载。 – 2011-04-30 17:45:03

回答

1

即使你提到你不想关闭延迟加载我坚持你这样做,因为延迟加载将始终触发,当你访问的导航属性第一次。避免这种情况的唯一方法是:

  • 关闭延迟加载。缺点是您必须关闭整个类别处理的延迟加载。因为一旦你打开它,它会立即重新加载Links在下次访问该属性。原因是用于处理LinksEntityCollection具有属性IsLoaded,该属性为假(并且除通过调用Load之外不能修改)。
  • 删除virtual关键字Links集合。这将不允许通过动态代理包装Category,因此它不允许延迟加载。它会更加有趣,因为加载中唯一需要的代码应该是前两行 - 链接将在第二次查询执行期间自动填充到类别。这里的问题是从自动生成的实体中删除虚拟关键字很难(它必须被硬编码为T4模板),或者您必须使用自己的实体。
  • 以某种方式欺骗EF,将Links属性中的EntityCollection替换为另一个集合。这并不容易,因为您不能仅将新集合分配给Links - 动态代理将抛出InvalidOperationException。您必须创建实体的第二部分,并添加一些代码,这些代码将直接修改保存集合的私有字段(绕过属性)。即使是这样的方法也会有一些不好的后果默认代码使用一些修正等

关闭延迟加载不会打破你的功能 - 实际上EF在内部经常这样做。你只需要做:

context.ContextOptions.LazyLoadingEnabled = false; 
相关问题