即使ObjectContext.ContextOptions.LazyLoadingEnabled = false,也会延迟加载导航属性

时间:2010-10-21 19:03:47

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

我注释掉了代码行,它为我的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();
    }

1 个答案:

答案 0 :(得分:4)

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

基本上,这行代码:

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

_context.Categories.AsEnumerable()

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

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"));
}


LazyLoading已停用
没有任何事情发生,代码永远不会进入foreach,因为cateogry.Expenses.Count == 0

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