EF4: Lazy Loading on By Default but what about pre Beta 2 Models?

There are two changes to the lazy loading feature introduced in the Beta 1 version of Entity Framework.

The first is that the property, ObjectContext.ContextOptions.DeferredLoadingEnabled has been changed to ObjectContext.ContextOptions.LazyLoadingEnabled.

This is a breaking change from Beta 1 and you’ll need to update references to this property.

The bigger change is that LazyLoadingEnabled is true by default for new models.

What exactly does this mean?

When you use the EDM Wizard to create a new model from an existing database, a new annotation is placed in the ENtityContainer element in the CSDL.

 <EntityContainer Name="MyEntities" annotation:LazyLoadingEnabled="true">

Annotations in CSDL are code generator directives. The result of this, when using the default code generation template, is that the constructors for the EntityContainer will set LazyLoadingEnabled=true.

Here is one of the three default constructors created for the container

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

Now whenever you instantiate a new MyEntities context, by default lazy loading is on.

So if you query for customers and do not eager load (Customer.Include(“Orders”)) or project (…select c, c.Orders…) related orders, you will not have to do anything more than ask for them (e.g., mycust.Orders.Count()) to fire off a behind the scenes database query  to retrieve the related data.

If you explicitly set LazyLoadingEnabled=false, then you are required to explicitly load related data as with ENtity Framework version 1.

What about old models?

If you have a model from before Beta 2 and are bringing it into this version and you want it to have lazy loading on by default, just open the model up in the XML editor and add the annotation in manually.

#1 fabrizio on 10.21.2009 at 2:07 AM

I remember past articles from many sources. They said: "Lazy Loading is evil. Linq to sql is evil. EF is good. EF does not use lazy loading."

I'm wrong? What changed in the meantime?

#2 Julie on 10.21.2009 at 9:50 AM

Lazy loading makes me nervous. If you come from a datareader/dataset background you would never have this expectation. I questioned the EF team a number of times about making it the default but they said that a) there was a big demand for it and b) it lines up with LINQ to SQL and almost every other ORM tool out there. (Not that I know of one that doesn't lazy load). Originally, they had the same perspective as me - be explicit about calls to the database. But over the course of the past two years, their opinion has shifted. So now my job is just to be sure people are VERY aware of what's happening in the background when you lazy load.

#3 fabrizio on 10.21.2009 at 10:18 AM

Julie, you confirmed my ideas. :)

I come from Typed DataSet and, yes, I don't need Lazy Loading. More: I don't want it. Ok, ok, I can disable it. But, IMHO, it's better to know what I need and explicitely query the DB.

So, IMHO, Lazy Loading should be turned OFF by default.

#4 Alex James on 10.21.2009 at 10:40 AM

fabrizio,

Julie is right overtime our opinion shifted. The fact is that the DDD / ALT.NET people will swear till they are blue in the face that LazyLoading is vital.

I'm not the best person to represent their position but I think the reasoning is that your client code shouldn't have any *visible* dependency on the ORM / plumbing infrastructure, and the only way to achieve this is using *invisible* Lazy-Loading.

Alex

#5 ian on 10.21.2009 at 10:41 AM

On by default is good. Novices will find this much easier. I'm also a fan of not optimizing something that doesn't need optimizing - so unless there's an ACTUAL performance issue in your application you shouldn't complicate it unnecessarily.

Compilers keep getting smarter - saying what you want rather than how to get it will allow them to do their job better in the future.

#6 Dane on 10.21.2009 at 10:46 AM

I can see some instances where it would be nice to have, but I don't think it should be on be default. At the very least when you create a new data model, there should be a checkbox that gives you the option to turn it on or off. I know that lazy loading is one option in ORMs that make DBAs very nervous.

I would personally like to see the team put in as an option when creating a model.

#7 Paul on 10.21.2009 at 4:57 PM

Alex basically sums up how I feel. I want to deal with domain objects and the problem at hand when writing my code.

Obviously I know under the hood that its calling the db but that is orthogonal to the business logic. being a good citizen I can optimize fetch strategies when I'm done.

#8 dan on 10.21.2009 at 6:46 PM

Lazy loading is actually a good concept its implemented on BizTalk server

#9 mdv on 10.21.2009 at 9:34 PM

How far does the lazy loading extend?

If you have:

Name

Address

PhoneNumbers

Does it automatically load just the references to Name or would it load all of the subsequent references encountered as it traverses the entities?

#10 Rick Ratayczak on 10.22.2009 at 12:33 AM

Why does this stuff have to change all the time?

Lazy loading is good or bad depending on the design.