【问题标题】:Lazy loading not working for POCO classes in Entity Framework延迟加载不适用于实体框架中的 POCO 类
【发布时间】:2012-01-18 21:21:20
【问题描述】:

请帮助我,我是 EF 新手。POCO 对象的延迟加载似乎不起作用。

  • 我的 POCO 类在一个单独的程序集中,而不是用于数据访问(即 DAL)的程序集
  • Data Acess 层只是封装了对 EF 对象上下文的调用。请看下面的代码

    public FilterMaster GetFilter(long ID)
    {
        FilterMaster entity = new FilterMaster();
        try
        {
            using (var context = new RadarEntities())
            {                
                //context.ContextOptions.LazyLoadingEnabled = false;
                //context.ContextOptions.ProxyCreationEnabled = true;
                entity = context.FilterMasters.SingleOrDefault(filter => filter.ID == ID);
                //context.FilterMasters.Include(
                context.LoadProperty(entity, "SQLQuery");                   
    
            }
        }
    
    • DAL 调用完成后,ObjectContext 丢失,当我尝试获取 Root POCO 类的相关子对象时,我得到 null。
    • 我已尝试显式启用 ProxyCreation、EnabledLazyLoading,检查生成的代理类未密封并且所有相关属性都标记为虚拟(如其他一些链接中所建议的那样)。 - 由于延迟加载不起作用,我想急切地加载所有相关的 POCO 对象,所以尝试调用 LoadProperty 方法,它有效。

Q1:我错过了延迟加载不起作用的东西吗?

Q2:如果我想明确加载所有相关的子对象,则必须为所有属性调用 LoadProperty 方法,还是有更简单的方法?

【问题讨论】:

    标签: c# entity-framework entity-framework-4


    【解决方案1】:

    您正在处理您的ObjectContext。这就是阻止您使用 LazyLoading 的原因。如果需要 LazyLoading,包含GetFilter 的类在创建时应该创建一个ObjectContext,实现IDisposable,并在销毁时销毁ObjectContext

    【讨论】:

    • 但是 POCO 的目的将被打败,因为 gthen 将成为持久性意识。目前只有 DAL API 引用了 ObjectContext。
    • @BrikeshKumar:但是您的上层有对 DAL API 类的引用(或者可能只是一个接口)。您只需要将ObjectContext 作为该类中的私有成员,并且不要在每个方法中创建和处置它。上层仍然看不到有关上下文的任何内容。如果您出于某种原因无法做到这一点,那么您的架构对延迟加载不友好,并且不能真正使用延迟加载。
    • 谢谢 Slauma !!我正在尝试。我将对象上下文类从 DAL 项目中取出,并将其实例注入 DAL 类构造函数中...当前遇到上下文类无法找到元数据的问题..
    • @BrikeshKumar 太好了。请不要忘记接受其中一个答案。
    【解决方案2】:

    Q1:我错过了延迟加载不起作用的东西吗?

    它工作正常,但不涉及任何魔法 - 在下面为您创建了一个代理,它将在您第一次访问时尝试从数据库中检索属性值。

    对于 EF,数据库连接由上下文表示,您当前在 using 块的末尾自动处理该上下文。如果没有数据库连接,EF 无法延迟检索属性,因此延迟加载将不起作用。

    在访问延迟加载所需访问的所有属性之前,您必须保持上下文处于活动状态,或者急切地加载这些属性。

    Q2:如果我想显式加载所有相关的子对象 将不得不为所有属性或那里调用 LoadProperty 方法 有更简单的方法吗?

    是的,您可以指定一个Include() 查询来急切地检索属性,在您的情况下是:

     entity = context.FilterMasters
                     .Include("SQLQuery")
                     .SingleOrDefault(filter => filter.ID == ID);
    

    【讨论】:

    • 我认为只有Include 的字符串版本,因为contextObjectContext
    • 感谢Slauma,我已经习惯了强类型版本,会更新
    • 是的,我只看到一个接受字符串的 Include 函数版本。此外,如果我进行急切加载,那么我将为整个对象图中的每个属性写一行。
    • BrokenGlass,有没有一种方法可以预先加载整个对象图,而无需在 Include 函数中指定每个依赖对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多