【问题标题】:Navigational properties lazily loaded even when ObjectContext.ContextOptions.LazyLoadingEnabled = false即使在 ObjectContext.ContextOptions.LazyLoadingEnabled = false 时,导航属性也会延迟加载
【发布时间】:2010-10-22 07:06:22
【问题描述】:

我注释掉了允许从我的 ObjectContext 类的所有 ctor 重载中延迟加载的代码行,但是当我迭代导航属性时,迭代是成功的。为什么?

这是相关的代码。

    public MyExpensesEntities() : 
                 base("name=MyExpensesEntities", "MyExpensesEntities")
    {
        // this.ContextOptions.LazyLoadingEnabled = true;
        OnContextCreated();
    }

    static void Main(string[] args)
    {
    AddExpenses();

       Console.WriteLine("Lazy loading is {0}.", 
                         _context.ContextOptions.LazyLoadingEnabled ? 
                         "enabled": "disabled");

       PrintCategorywiseExpenses();

   _context.Dispose();
       Console.WriteLine("Press any key to exit...");
   Console.ReadKey();
    }

 static void PrintCategorywiseExpenses()
    {
        foreach (var cateogry in _context.Categories)
        {
            Console.WriteLine
                            ("Category: {0}\n----------------", 
                             cateogry.CategoryName);

            foreach (var e in cateogry.Expenses)
                Console.WriteLine
                                    ("\tExpense: {0}\tAmount: {1}", 
                                     e.Particulars, e.Amount.ToString("C"));
        }

        Console.WriteLine();
    }

【问题讨论】:

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


    【解决方案1】:

    您应该知道,通过在导航属性上执行foreach,您明确要求 EF 为您加载它,并且仅仅因为您关闭延迟加载并不意味着您以后不能明确加载它们。因此,一旦它被禁用,您仍然可以根据需要显式加载相关数据,而这正是您使用 foreach 时发生的情况。 “延迟加载”的另一个术语实际上是“隐式延迟加载”,它不会阻止我们这样做“显式延迟加载”

    基本上就是这行代码:

    foreach (var cateogry in _context.Categories)
    几乎等同于:
    _context.Categories.AsEnumerable()
    

    要查看禁用延迟加载如何影响您的代码,请参见下面的示例。
    在此示例中,我禁用它并读取您的 Categories 之一,然后处理 ObjectContext 并在 Expenses 上执行 foreach:

    Category category;
    using (MyEntities context = new MyEntities()) {
        category = _context.Categories.First();
    }
    
    foreach (var e in cateogry.Expenses)
          Console.WriteLine("Expense:{0}", e.Amount.ToString("C"));
    }
    


    延迟加载已禁用
    没有任何反应,代码将永远不会进入 foreach,因为 cateogry.Expenses.Count == 0

    已启用延迟加载
    EF 尝试延迟加载费用,并且由于 ObjectContext 已被释放(通过 使用 范围),您将获得 System.ObjectDisposedException包含此消息:
    The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

    【讨论】:

    • 那导航属性什么时候没有加载呢?那么将延迟加载设置为 false 会如何影响导航属性的延迟加载呢?请给我一个延迟加载关闭且导航属性无法访问的示例?
    • 当然,我刚刚在我的答案中添加了一个代码 sn-p 来说明它,请检查一下。
    • 非常感谢您的回答。我还在重新阅读它并更深入地思考它。我很快就会在 cmets 有更多问题。
    • 不错的答案,尽管您发布了不可能的代码行:var category;如果没有为 C# 中的变量赋值,就不能使用“var”关键字,因为没有勺子……等等……什么?我的意思是,C# 中没有无类型变量^^
    • 是的,那只是因为我不知道他的 Categories ObjectSet 的实体对象的名称。假设它是Category。我已经更改了代码。你是对的,对于匿名类型,你将在声明行初始化变量,否则编译器会抱怨。感谢您的提醒:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 2011-08-11
    • 1970-01-01
    相关资源
    最近更新 更多