Controlling eager and lazy loading in LightSpeed models
Tagged as LightSpeedLightSpeed’s system of eager and lazy loading provides an extremely convenient and efficient way to tune performance without troubling application code with the details of when and how to access the database. The key concept here is that of named aggregates, an abstraction layer which allows an application to say what it wants to use the entity for, and lets the entity designer map that down to specific fields to load.
Let’s review how this works. By default, when you load an entity (using Find, FindOne or LINQ), LightSpeed retrieves from the database all the value fields of that entity, but doesn’t retrieve the data for any associated entities or collections. For example, when you load an Employee entity, LightSpeed fetches the Name, ManagerId and Photo, but doesn’t load the Manager entity, or populate the DirectReports collection. When somebody references these associations, LightSpeed goes back to the database at that point.
Sometimes it makes sense to tune this default based on expected usage. If the main consumer of Employee entities is a program which draws org charts, it may be a good idea to load the DirectReports collection while you’re fetching the Employee, because otherwise you’ll just have to go back a microsecond later. You can do this using the EagerLoad attribute.
Similarly, a program for drawing org charts probably doesn’t need to load the Photo property, which might be quite a large bitmap, all the time — only when somebody actually chooses to drill in and look at the photo. We could add a “lazy load” attribute for this, but that’s not always a great solution because often an entity has several fields that are often used together. For example, our Employee record might include fields that are of interest to the holiday approval page, such as the date the employee started work, the number of vacation days outstanding, etc. We don’t want to load these all the time, because most users of Employee objects don’t care; but naively marking each with our hypothetical LazyLoad attribute would mean that the holiday approval page would trigger several round-trips to the database, fetching one field at a time. To avoid this, LightSpeed implements lazy loading as “eager loading of named aggregates.” We label each holiday-specific fields as [EagerLoad("Holiday")]. Then in the holiday approval page, when we load the Employee, we specify the “Holiday” aggregate. LightSpeed eager-loads any fields tagged as [EagerLoad("Holiday")], resulting in only a single visit to the database to fetch everything the holiday page needs. Fields that are tagged as part of an aggregate other than “Holiday” are left for lazy-loading. A field can be part of more than one named aggregate. The employee start date, for example, might be of interest to the performance review subsystem as well as the holiday subsystem.
So by applying EagerLoad attributes to associations, collections and fields, we can make very efficient use of the database without coupling the application layer to the details of the optimisations. With LightSpeed 2, however, you may be using the visual model designer and getting it to create your code for you, so you can’t add the required attribute or attributes by hand. Instead, you can set up the eager loading control via the designer.
To mark a collection as (always) eager-loaded, select the association, go to the Properties window, and set EagerLoad to true:
To mark a collection or property as part of a named eager-load aggregate, select the association or property, go to the Properties window, and enter the name in the Aggregates box:

If the item is part of more than one aggregate, separate them with semi-colons.
You can also mark properties as part of an aggregate via the Model Explorer: right-click the property and choose Add Aggregate.
If you mark an association as part of an aggregate, you don’t also need to set EagerLoad to true, even though the aggregate is represented at the code level by the EagerLoadAttribute. In fact, if you set EagerLoad on an association, there’s no point having named aggregates on it as well, because the association will always be eager-loaded.
2 Responses to “Controlling eager and lazy loading in LightSpeed models”
Leave a Reply
Categories
BrainDump (1)
Community Code (4)
Events (16)
F# (14)
General (53)
Lab Samples (2)
LightSpeed (268)
MegaPack (8)
News (71)
NHibernate Designer (26)
Nightly news (52)
Phone Elements (24)
Products (87)
Projects (5)
Screencast (6)
SharePoint (3)
Silverlight (14)
Silverlight Elements (66)
SimpleDB Management Tools (20)
Visual Studio (9)
VS File Explorer (7)
Web Workbench (39)
WPF (44)
WPF Diagrams (57)
WPF Elements (110)
WPF Property Grid (32)




Posted by Ivan Towlson on 30 June 2008 



…For example, when you load an Employee entity, LightSpeed fetches the Name, ManagerId and _Photo_, but doesn’t load the Manager entity, or populate the DirectReports collection….
and later on you’re writing that there’s no need (or way?) to mark Photo as lazy load, because we have eager loading with named aggregates.
…We could add a “lazy load†attribute for this, but that’s not always a great solution because often an entity has several fields that are often used together….
as I see it, photo will be allways loaded when fetching employee entity object, so the only way to not load BLOB data is to put photo to another entity when loading employee entity…
or is there any lazy load attribute I have missed? when photo is a field/property that way it will allways load with the same entity it is in, if it is not collection wouldn’t it?
OR wait a second…now I’m thinking ;) Ok I’m not perfect english speaker, but did you mean that when I want to load just a few properties of an entity (I want that entity directly but not all its fields, properties etc) I can make it through named aggregates. That way only marked fields for an entity will load… Or am I lost? ;)))
Hi nefajciar,
Non-association type fields (like byte[]) are eager by default. However, if you mark such a field with a named aggregate, then it is lazy _unless_ you specify that aggregate as part of your query.
Cheers,
Andrew.