【问题标题】:Entity Framework 4 selective lazy loading propertiesEntity Framework 4 选择性延迟加载属性
【发布时间】:2010-07-18 03:50:52
【问题描述】:

是否可以加载不包括某些属性的实体?该实体的属性之一选择起来很昂贵。我想延迟加载这个属性。这可能吗?

【问题讨论】:

    标签: entity-framework ado.net entity-framework-4


    【解决方案1】:

    既然您已经阅读了大家的回复,我将给您正确的答案。 EF 不支持延迟加载属性。然而,它确实支持一个非常强大的概念然后这个。这称为表拆分,您可以将表映射到两个实体。假设数据库中的一个产品表可以映射到产品实体和ProductDetail实体。然后,您可以将昂贵的字段移动到 ProductDetail 实体,然后在 prodcut 和 productdetail 实体之间创建 1..1 关联。然后,您可以仅在需要时才延迟加载 productdetail 关联。 在我书中的表演章节中,我有一个名为的食谱。 13-9。将昂贵的财产转移到另一个实体

    希望有帮助!

    Julie Lerman has an article on how to split a table

    【讨论】:

    • 谢谢。我必须这样做。但是 EF4 应该支持对标量属性的延迟加载,它真的很方便。
    • 我知道团队正在努力在下一个版本中支持开箱即用的延迟加载属性,但我确实认为将昂贵的列移动到另一个实体开辟了一次延迟加载多个昂贵属性的途径。想象一下,您有一个包含 EmployeePicture 和 employeedescription 的员工对象,它们都很昂贵,并且您想延迟加载它们,但是无论何时要加载它们,都希望将它们一起加载。这是 linq to sql 做不到的。
    • 是的,如果有多个昂贵的字段,在这种情况下,EF 团队可以启用像 LoadAllLazyProperties 这样的标志,它允许 EF 一起加载标记为延迟加载的所有标量属性,无论何时请求它们中的任何一个.这可以改善您提到的情况,而无需分离 EntityTypes!
    【解决方案2】:

    对于标量属性,选择性地不加载某个属性的唯一方法是在 ESQL 或 L2E 中进行投影:

    var q = from p in Context.People
            select new
            {
                Id = p.Id,
                Name = p.Name // note no Biography
            };
    

    +1 给丹;懒惰地这样做比预先加载它更糟糕。如果你想控制加载,请明确。

    【讨论】:

    • 感谢您的建议。是的,但这种预测效率不高。首先,它会导致无法直接用作 People 的匿名类型。必须正确创建和实例化一个新的 People 对象,这将浪费时间在对象之间进行解析。上下文也无法跟踪此类型。
    • @Nazaf,你过早地优化了。
    【解决方案3】:

    stimms 是正确的,但在使用延迟加载时要小心。您可能会遇到性能问题,并且没有意识到该属性正在代码中的特定位置加载。这是因为它会在您使用该属性时加载数据

    我更喜欢使用显式加载。这样您就可以知道它们何时加载以及在何处加载。这是一个链接,它给出了 LoadProperty http://sankarsan.wordpress.com/2010/05/09/ado-net-entity-framework-data-loading-part-2/ 的示例

    您也可以使用 Include 方法进行 Eager Loading。此处示例:http://wildermuth.com/2008/12/28/Caution_when_Eager_Loading_in_the_Entity_Framework

    【讨论】:

    • stimms 和 Dan,我不是指相关属性,我指的是像 Biography(C# 中的字符串或 SQL Server 中的 varchar(1024))这样的字段(类成员),这真的很昂贵要加载实体,我想在必要时延迟加载它。据我所知,这在 EF4 中不起作用。有办法吗?
    • 所以你想延迟加载一个标量属性?就在我的脑海中,我可能会尝试将传记拆分为实体并将其设置为导航属性。然后我就可以懒惰/急切/急切地加载它。可能有更好的方法...有机会我会测试这个理论。
    • 谢谢,这似乎是唯一有效的方法。
    【解决方案4】:

    鉴于对 EntityFramework DbSet 的查询,其中目标实体包含 BigProperty 和 SmallProperty, 你试图只访问 SmallProperty 而不将 BigProperty 加载到内存中时:

    //this query loads the entire entity returned by FirstOrDefault() in memory
    //the execution is deferred during Where; the execution happens at FirstOrDefault
    db.BigEntities.Where(filter).FirstOrDefault()?.SmallProperty;
    
    //this query only loads the SmallProperty in memory
    //the execution is still deferred during Select; the execution happens at FirstOrDefault
    //a subset of properties can be selected from the entity, and only those will be loaded in memory
    db.BigEntities.Where(filter).Select(e=>e.SmallProperty).FirstOrDefault();
    

    因此,您可以利用此行为仅在您实际需要的地方查询 BigProperty,并使用 select 语句在其他任何地方显式过滤掉它。

    我使用 Visual Studio 调试诊断工具中的内存使用功能对此进行了测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多