Navigational properties lazily loaded even when ObjectContext.ContextOptions.LazyLoadingEnabled = false
I commented out the line of code that enables lazy loading from all the ctor overloads for my ObjectContext class, yet when I iterate over a navigational property, the iteration is successful. Why?
Here's the relevant bits of code.
public MyExpensesEntities() :
base("name=MyExpensesEntities", "MyExpensesEntities")
{
// this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
static void Main(string[] args)
{
AddExpenses开发者_JAVA百科();
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();
}
You should be aware that by doing a foreach
over a navigation property you are explicitly ask EF to load it for you and just because you turn off the Lazy Loading does not mean that you cannot explicitly load them later. So, once it is disabled, you can still explicitly load related data on demand if needed and that's exactly what happened when you use foreach
. Another term for "Lazy Loading" is actually "implicit deferred loading" and it will not prevent us from doing an "Explicit deferred loading"
Basically, this line of code:
foreach (var cateogry in _context.Categories)
is almost equivalent to this:
_context.Categories.AsEnumerable()
To see how disable lazy loading affect your code see the example below.
In this example, I disable it and read one of your Categories then dispose the ObjectContext and do the foreach over 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 is Disabled:
Nothing happens, the code will never get into the foreach since the cateogry.Expenses.Count == 0
LazyLoading is Enabled:
EF tries to lazy load Expenses and since the ObjectContext has been disposed (by going out of using scope) you'll get an System.ObjectDisposedException containing this message:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
精彩评论