<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jaroslaw Kowalski : EFLazyLoading</title><link>http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx</link><description>Tags: EFLazyLoading</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Entity Framework samples converted to Visual Basic </title><link>http://blogs.msdn.com/jkowalski/archive/2009/05/21/entity-framework-samples-converted-to-visual-basic.aspx</link><pubDate>Thu, 21 May 2009 20:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9634089</guid><dc:creator>jkowalski</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jkowalski/comments/9634089.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jkowalski/commentrss.aspx?PostID=9634089</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jkowalski/rsscomments.aspx?PostID=9634089</wfw:comment><description>&lt;P&gt;We have recently published Visual Basic versions of our MSDN Code Gallery samples for Entity Framework v3.5SP1.&lt;/P&gt;
&lt;P&gt;The following translated samples are currently available in two languages (C# and VB)&lt;/P&gt;
&lt;P&gt;ADO.NET Entity Framework Query Samples&lt;BR&gt;&lt;A href="http://code.msdn.com/EFQuerySamples" mce_href="http://code.msdn.com/EFQuerySamples"&gt;http://code.msdn.com/EFQuerySamples&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Persistence Ignorance (POCO) Adapter for Entity Framework&lt;BR&gt;&lt;A href="http://code.msdn.com/EFPocoAdapter" mce_href="http://code.msdn.com/EFPocoAdapter"&gt;http://code.msdn.com/EFPocoAdapter&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Transparent Lazy Loading for Entity Framework&lt;BR&gt;&lt;A href="http://code.msdn.com/EFLazyLoading" mce_href="http://code.msdn.com/EFLazyLoading"&gt;http://code.msdn.com/EFLazyLoading&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The samples have been fully converted to use and generate Visual Basic&amp;nbsp;code instead of C#. More samples are in the pipeline and will be published soon - stay tuned. &lt;/P&gt;
&lt;P&gt;Full list of current EF samples published by the Entity Framework team is always available at:&lt;BR&gt;&lt;A href="http://code.msdn.microsoft.com/adonetefx" mce_href="http://code.msdn.microsoft.com/adonetefx"&gt;http://code.msdn.microsoft.com/adonetefx&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9634089" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jkowalski/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx">EFLazyLoading</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFPocoAdapter/default.aspx">EFPocoAdapter</category></item><item><title>Transparent Caching Support for Entity Framework one-pager</title><link>http://blogs.msdn.com/jkowalski/archive/2008/07/10/caching-one-pager.aspx</link><pubDate>Thu, 10 Jul 2008 22:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8718220</guid><dc:creator>jkowalski</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jkowalski/comments/8718220.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jkowalski/commentrss.aspx?PostID=8718220</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jkowalski/rsscomments.aspx?PostID=8718220</wfw:comment><description>&lt;P&gt;We've just posted a one-pager on transparent caching support in Entity Framework on our &lt;A class="" href="http://blogs.msdn.com/efdesign/" mce_href="http://blogs.msdn.com/efdesign/"&gt;EFDesign blog&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/efdesign/archive/2008/07/09/transparent-caching-support-in-the-entity-framework.aspx"&gt;http://blogs.msdn.com/efdesign/archive/2008/07/09/transparent-caching-support-in-the-entity-framework.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We want to make sure that you will be able to interface EF caching with various caching solutions, so we would be very grateful for comments on proposed ICache interface.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8718220" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx">EFLazyLoading</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/Caching/default.aspx">Caching</category></item><item><title>Transparent Lazy Loading for Entity Framework – part 3 – Anatomy of a Stub</title><link>http://blogs.msdn.com/jkowalski/archive/2008/05/28/transparent-lazy-loading-for-entity-framework-part-3-anatomy-of-a-stub.aspx</link><pubDate>Wed, 28 May 2008 19:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8556704</guid><dc:creator>jkowalski</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jkowalski/comments/8556704.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jkowalski/commentrss.aspx?PostID=8556704</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jkowalski/rsscomments.aspx?PostID=8556704</wfw:comment><description>&lt;p&gt;This post is a part of the series that describes &lt;a href="http://code.msdn.microsoft.com/EFLazyLoading" target="_blank" mce_href="http://code.msdn.microsoft.com/EFLazyLoading"&gt;EFLazyLoading&lt;/a&gt; library.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx" target="_blank" mce_href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx"&gt;Part 1 - Strategies for implementing lazy loading&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx" target="_blank" mce_href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx"&gt;Part 2 - Implementation of EFLazyLoading&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/28/transparent-lazy-loading-for-entity-framework-part-3-anatomy-of-a-stub.aspx" target="_blank" mce_href="http://blogs.msdn.com/jkowalski/archive/2008/05/28/transparent-lazy-loading-for-entity-framework-part-3-anatomy-of-a-stub.aspx"&gt;Part 3 - Anatomy of a Stub&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In two previous articles I have introduced EFLazyLoading &amp;#8211; a framework for lazy loading of entities on top of Entity Framework. In this post I will explain what stubs are and how they work. &lt;/p&gt;  &lt;p&gt;Let&amp;#8217;s establish some terminology first:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Shell object&lt;/b&gt; is a public object that the users interact with. It has the properties of an entity, but no backing fields except for the primary key. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Data object&lt;/b&gt; is an internal data structure that has backing fields for the object. It implements ILazyEntityDataObject interface. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Stub object&lt;/b&gt; is a shell object that has no data object attached to it. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Fully loaded&lt;/b&gt; &lt;b&gt;object&lt;/b&gt; is a shell that has a data object attached and populated. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here is a typical pair of shell and data objects &amp;#8211; NorthwindEF.Category. Note a few things:&lt;a href="http://blogs.msdn.com/blogfiles/jkowalski/WindowsLiveWriter/d78d5e1ac24d_801B/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/jkowalski/WindowsLiveWriter/d78d5e1ac24d_801B/image_2.png"&gt;&lt;img height="619" alt="Structure of the Category entity" src="http://blogs.msdn.com/blogfiles/jkowalski/WindowsLiveWriter/d78d5e1ac24d_801B/image_thumb.png" width="252" align="right" border="0" mce_src="http://blogs.msdn.com/blogfiles/jkowalski/WindowsLiveWriter/d78d5e1ac24d_801B/image_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;_CategoryID is the only field in the shell class (disregard the base class for a while). All other fields are declared in the data class &lt;/li&gt;    &lt;li&gt;The only public properties on the shell class are properties that correspond to EntityType definition. &lt;/li&gt;    &lt;li&gt;Data class is a nested type inside the shell class. &lt;/li&gt;    &lt;li&gt;Data class is a backing store for all non-key properties. &lt;/li&gt;    &lt;li&gt;Data objects must be able to deep-clone themselves. This is the purpose of ILazyEntityDataObject.Copy() method. &lt;/li&gt;    &lt;li&gt;Data properties (see previous article) are also declared in the Data class. This is because of pure convenience as it enables fields to be private. &lt;/li&gt;    &lt;li&gt;There are no public methods &amp;#8211; only protected CreateDataObject() which takes care of creating a private data object. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Shell objects implement ILazyEntityObject interface in addition to three IPOCO interfaces: IEntityWithKey, IEntityWithChangeTracking and IEntityWithRelationships. In current implementation those interfaces are implemented in the base class called LazyEntityObject.&lt;/p&gt;  &lt;p&gt;Data object in current implementation it is implemented as a class with fields, but in theory it could be implemented as a hash table (to allow for types with huge number of nullable columns that are often nulls) or in some other way.&lt;/p&gt;  &lt;h4&gt;How stubs are born&lt;/h4&gt;  &lt;p&gt;Stubs can come to life in four possible ways:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Relationship navigation &amp;#8211; when navigating a many-to-one relationship, a stub object is created to represent the related end (if the entity is not already being tracked by the ObjectStateManager). &lt;/li&gt;    &lt;li&gt;IQueryable&amp;lt;T&amp;gt;.AsStubs(). It is possible to construct a sequence of stubs (IEnumerable&amp;lt;T&amp;gt;) by calling AsStubs() on IQueryable&amp;lt;T&amp;gt;. This will convert a query to a query that only projects primary keys (thus saving on database connection bandwidth). &lt;/li&gt;    &lt;li&gt;IQueryable&amp;lt;T&amp;gt;.GetStub() that returns a single result. This is a stub equivalent of calling First(). &lt;/li&gt;    &lt;li&gt;It is also possible to populate LazyEntityCollection with stub objects (instead of fully loaded objects) by calling LoadStubs() method. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There is also a way for unmodified fully loaded object to become stub again. All you have to do is to discard their data object by calling LazyObjectContext.Reset() or by calling LazyObjectContext.ResetAllUnchangedObjects() which does the same thing for all unmodified objects in the context. This can help reduce memory footprint of your unit of work, when you are dealing with large objects and you are done processing them. Instead of detaching an object from the context, you simply discard its data &amp;#8211; object identity is preserved and it can still be found in all relationships it belongs to, but most of objects memory can be reclaimed by GC.&lt;/p&gt;  &lt;h4&gt;Examples&lt;/h4&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// instantiate a fully loaded entity&lt;/span&gt;
var prod = entities.Products.First();

&lt;span class="rem"&gt;// stub gets created because of relationship navigation - no load from the database here&lt;/span&gt;
var cat = prod.Category; 

&lt;span class="rem"&gt;// category object gets fully loaded on first property access&lt;/span&gt;
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;name: {0}&amp;quot;&lt;/span&gt;, cat.CategoryName);

&lt;span class="rem"&gt;// once it is loaded we can access all properties - no database access here&lt;/span&gt;
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;desc: {0}&amp;quot;&lt;/span&gt;, cat.Description);

&lt;span class="rem"&gt;// iterate through details&lt;/span&gt;
&lt;span class="rem"&gt;// note that collection is populated with LoadStubs which only brings keys&lt;/span&gt;
&lt;span class="rem"&gt;// into memory&lt;/span&gt;
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (OrderDetail det &lt;span class="kwrd"&gt;in&lt;/span&gt; prod.OrderDetails.LoadStubs())
{
    &lt;span class="rem"&gt;// order can be Order or InternationalOrder so it will be eagerly loaded&lt;/span&gt;
    &lt;span class="rem"&gt;// because we don't know the concrete type (see below)&lt;/span&gt;
    &lt;span class="rem"&gt;// next time (even in a different ObjectContext) we'll use cached type information&lt;/span&gt;
    &lt;span class="rem"&gt;// so there's no server roundtrip&lt;/span&gt;
    var order = det.Order;

    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0} {1}&amp;quot;&lt;/span&gt;, det.Product.ProductName, order.OrderDate);
}

&lt;span class="rem"&gt;// execute a query and return collection of stub objects&lt;/span&gt;
var stubs = entities.Suppliers.Where(c =&amp;gt; c.Products.Any(d=&amp;gt;d.Category.CategoryID == cat.CategoryID)).AsStubs();

&lt;span class="rem"&gt;// iterate over stubs - as we go through the collection, individual suppliers are loaded on-demand&lt;/span&gt;
&lt;span class="kwrd"&gt;&lt;span class="rem"&gt;// note how LoadStubs() is used to count Products without fully loading them&lt;/span&gt;
foreach&lt;/span&gt; (var p &lt;span class="kwrd"&gt;in&lt;/span&gt; stubs)
{
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Shipper {0} - {1} - {2} products&amp;quot;&lt;/span&gt;, p.CompanyName, p.Phone, p.Products.LoadStubs().Count);
}

&lt;span class="rem"&gt;// execute a query that returns a single stub object&lt;/span&gt;
var singleStub = entities.Suppliers.GetStub(c=&amp;gt;c.SupplierID == 4);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Stub: {0}&amp;quot;&lt;/span&gt;, singleStub.Phone);&lt;/pre&gt;

&lt;h4&gt;Problem with polymorphic types&lt;/h4&gt;

&lt;p&gt;Despite our intention, we sometimes get fully loaded objects instead of stubs when calling one of the above methods &amp;#8211; that is because of polymorphic types. For example, when your schema has a Customer base type and InternationalCustomer type derived from and there is an association from Order to Customer, you can get either a customer or international customer when you navigate the association:&lt;/p&gt;

&lt;p&gt;We cannot possibly know the concrete type up front by examining its EntityKey. Unfortunately to create a stub/shell object we need to know the CLR type. When doing eager load, Entity Framework materializer takes care of determining concrete type by sending a specially crafted SQL query down to the server. The query includes a special discriminator column down which is used to resolve back to concrete type. Unfortunately in this case we don&amp;#8217;t want to send any query. Even if we wanted to do that, neither Entity SQL nor LINQ have a way to project object type without loading full object, so store cannot really help us here.&lt;/p&gt;

&lt;h4&gt;Enter IObjectTypeCache&lt;/h4&gt;

&lt;p&gt;IObjectTypeCache is one proposed solution to this problem. It exploits the fact, that (using normal methods) objects never change their type &amp;#8211; there is no way to change the class of an entity stored in a database table, because Entity Framework does not allow inheritance discriminator columns (in TPH mapping) to be written to and there is no way to achieve the same thing in case of TPT or TPC mappings.&lt;/p&gt;

&lt;p&gt;IObjectTypeCache s a cache whose keys are EntityKey objects and values are CLR types (in fact they are factory methods that return objects). This gives us amortized low cost of determining the type given a CLR type.&lt;/p&gt;

&lt;p&gt;Every time we create a stub (of type T), we check whether the EntityType has subclasses (defined in CSDL). If the type is known to not to be polymorphic, we just create a new instance of T.&lt;/p&gt;

&lt;p&gt;If the type can have subclasses, we check whether the mapping from EntityKey to type is found in cache &amp;#8211; if it is there &amp;#8211; we just call the factory method and the stub is ready.&lt;/p&gt;

&lt;p&gt;If the mapping is not found in the cache (which typically happens the first time a particular EntityKey is materialized in an application), we don&amp;#8217;t try to create stubs at all &amp;#8211; we fall back to running the fully materialized query which resolves the type for us. After this is done, we add newly discovered key-to-type mappings to our cache, so that the mappings are known next time.&lt;/p&gt;

&lt;p&gt;There is a singleton object that holds a reference to IObjectTypeCache that all LazyObjectContexts will use &amp;#8211; it is currently held in a static property of LazyObjectContext called ObjectTypeCache.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;WARNING: &lt;/b&gt;The default implementation of IObjectTypeCache (as of EFLazyLoading v0.5) does not do any cache eviction. This is typically not a problem for databases that have about one million of polymorphic objects (cache can grow up to consume 30-50MB of RAM which is usually not a problem nowadays). If your application has to scale to support more polymorphic objects than that, the sample has to be modified to add some automatic eviction (based on LRU, LFU or other strategy).&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8556704" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jkowalski/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx">EFLazyLoading</category></item><item><title>Transparent Lazy Loading for Entity Framework – part 2</title><link>http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx</link><pubDate>Mon, 12 May 2008 23:49:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8496771</guid><dc:creator>jkowalski</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/jkowalski/comments/8496771.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jkowalski/commentrss.aspx?PostID=8496771</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jkowalski/rsscomments.aspx?PostID=8496771</wfw:comment><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;This post is a part of the series that describes &lt;a href="http://code.msdn.microsoft.com/EFLazyLoading" target="_blank"&gt;EFLazyLoading&lt;/a&gt; library.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx" target="_blank"&gt;Part 1 - Strategies for implementing lazy loading&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx" target="_blank"&gt;Part 2 - Implementation of EFLazyLoading&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/28/transparent-lazy-loading-for-entity-framework-part-3-anatomy-of-a-stub.aspx" target="_blank"&gt;Part 3 - Anatomy of a Stub&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As I promised &lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx"&gt;last time&lt;/a&gt;, I would like to present the result of a little experiment in implementing transparent lazy loading for Entity Framework. You can download the sample code &lt;a href="http://code.msdn.microsoft.com/EFLazyLoading"&gt;here&lt;/a&gt;, the rest of this post tries to explain how it all works.&lt;/p&gt;  &lt;h3&gt;Requirements&lt;/h3&gt;  &lt;p&gt;I set myself some goals:&lt;/p&gt;  &lt;p&gt;a) Objects should be code-generated in a way similar to the standard Entity Framework code generation and the resulting code&amp;#8217;s public surface should be similar. There will be some differences in the way collections and references are handled.&lt;/p&gt;  &lt;p&gt;b) Collections should be represented by classes that implement ICollection&amp;lt;T&amp;gt; and should always be ready to use without &amp;#8220;IsLoaded/Load&amp;#8221;.&lt;/p&gt;  &lt;p&gt;c) EntityReference&amp;lt;T&amp;gt; and EntityCollection&amp;lt;T&amp;gt; should be completely hidden from the user&lt;/p&gt;  &lt;p&gt;d) Each (N-to-0..1) reference should be represented solely by a property where the type is the target object type (no EntityReference&amp;lt;T&amp;gt; properties in the object layer).&lt;/p&gt;  &lt;p&gt;e) We don&amp;#8217;t want to materialize the object at the other end of the relationship just to see whether it is null or not:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;Order o;

&lt;span class="kwrd"&gt;if&lt;/span&gt; (o.Customer != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;We have a customer!&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;f) We don&amp;#8217;t want to materialize the object if we don&amp;#8217;t care about its properties (for example changing &amp;#8220;Customer&amp;#8221; navigation property on &amp;#8220;o&amp;#8221; does not require the Customer object to be loaded at all - today we can use EntityKeys to achieve similar thing):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Order o;
Order o2;
o.Customer = o2.Customer;&lt;/pre&gt;

&lt;p&gt;g) Each object must be able to live in two states: loaded and unloaded and the object must be able to load itself on first access to the property. Unloaded objects that haven&amp;#8217;t been accessed are really just wrappers for the EntityKey, objects that have been touched have actual data:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Order o = ...;

&lt;span class="kwrd"&gt;if&lt;/span&gt; (o.Customer != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
    &lt;span class="rem"&gt;// loads o.Customer on-demand&lt;/span&gt;
    Console.WriteLine(o.Customer.Address.City);
}&lt;/pre&gt;

&lt;p&gt;h) Object in the unloaded state should be as cheap to create as possible.&lt;/p&gt;

&lt;h3&gt;Implementation&lt;/h3&gt;

&lt;p&gt;Because each object has to be delay-loadable and cheap to create, we are representing a single entity as a pair of objects. One is the &amp;#8220;shell&amp;#8221; that has all the properties and navigation properties of an entity and the EntityKey and the other that holds actual data (minus the key).&amp;#160; Property getters and setters on the shell class delegate read/write operations to the data class which is lazily created (to conserve memory when not needed).&lt;/p&gt;

&lt;p&gt;This is a pseudo-code that demonstrates this (_data management is not shown here &amp;#8211; actual _data reference and entity key is held in the base class)&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// shell class - has no fields to hold actual data, just &lt;/span&gt;
&lt;span class="rem"&gt;// a reference to lazy-initialized data object &amp;#8211;this will not compile&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Order
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; EntityKey _key; &lt;span class="rem"&gt;// each shell has an identity &lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; OrderData _data; &lt;span class="rem"&gt;// reference to lazy-initialized data&lt;/span&gt;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; OrderID 
    {
        get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _key.Something; }
        set { _key.Something = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime OrderDate
    { 
        get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _data.OrderDate; } 
        set { _data.OrderDate = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ShipTo
    {
        get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _data.ShipTo; }
        set { _data.ShipTo = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; BillTo
    {
        get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _data.BillTo; }
        set { _data.BillTo = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; Customer Customer { get; set; } &lt;span class="rem"&gt;// details not shown&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; ICollection&amp;lt;OrderLine&amp;gt; Lines { get; }
}

&lt;span class="rem"&gt;// data class - just a bunch of fields&lt;/span&gt;
&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OrderData
{
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; DateTime OrderDate;
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ShipTo;
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; BillTo;
}&lt;/pre&gt;

&lt;p&gt;For objects in &amp;#8220;unloaded&amp;#8221; stage there is just one object (Order), for loaded objects &amp;#8220;OrderData&amp;#8221; is initialized so property accesses actually work. The first time user accesses the property getter or setter and _data is null, the data is brought from the store.&lt;/p&gt;

&lt;p&gt;When the user navigates a {one,many}-to-one relationship we create a shell object that has only primary key initialized, attach it to the context and return to user. The Data object is not created at all and &amp;#8220;_data&amp;#8221; pointer is null. When a property is accessed for the first time, the data gets initialized by calling objectcontext.Refresh(StoreWins) which brings all properties and relationships into memory.&lt;/p&gt;

&lt;p&gt;Collections are rather simple &amp;#8211; all we have to do is return a wrapper over EntityCollection&amp;lt;T&amp;gt; that does Load() under the hood when the data is actually needed (for example in foreach()).&lt;/p&gt;

&lt;h3&gt;Implementation details&lt;/h3&gt;

&lt;p&gt;The implementation takes advantage of the fact that Entity Framework supports IPOCO. We introduce a base class called LazyEntityObject that all code-generated objects derive from, and that implements all interfaces required by Entity Framework (IEntityWithKey, IEntityWithChangeTracking, IEntityWithRelationships) and a new interface ILazyEntityObject. The implementation of these interfaces is done explicitly, which means that there is no single public API exposed on actual entity objects (not even EntityKey).&lt;/p&gt;

&lt;p&gt;In the actual implementation (compared to the pseudo-code) the data class is an inner private class of each entity class and property getters and setters are implemented through statically declared Data Properties &amp;#8211; a concept similar to WPF dependency properties. They are statically initialized with delegates that get/set actual data but perform all the needed operations under the hood (such as change tracking and lazy initialization). As a result everything is type-safe and there is no need to use reflection. Thanks to &lt;a href="http://blogs.msdn.com/meek/"&gt;Colin&lt;/a&gt; for the idea!&lt;/p&gt;

&lt;p&gt;With this in place the code generated for each property getter/setter is a simple one-liner, whether it is a simple property, a reference or a collection:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[EdmScalarPropertyAttribute(EntityKeyProperty=&lt;span class="kwrd"&gt;false&lt;/span&gt;, IsNullable=&lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; Single Discount
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; Data.DiscountProperty.Get(&lt;span class="kwrd"&gt;this&lt;/span&gt;); }
    set { Data.DiscountProperty.Set(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;value&lt;/span&gt;); }
}

[EdmRelationshipNavigationPropertyAttribute(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Order_Details_Order&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Order&amp;quot;&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; Order Order
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; Data.OrderProperty.Get(&lt;span class="kwrd"&gt;this&lt;/span&gt;); }
    set { Data.OrderProperty.Set(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;value&lt;/span&gt;); }
}&lt;/pre&gt;

&lt;p&gt;The Data class itself is also clean (just a bunch of fields + static data properties) and all the hard work is done in the implementation of Data Property classes.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Data : ILazyEntityObjectData
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Decimal UnitPrice;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Int16 Quantity;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Single Discount;

    &lt;span class="rem"&gt;// primary key&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataKeyProperty&amp;lt;OrderDetail,Int32&amp;gt; OrderIDProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataKeyProperty&amp;lt;OrderDetail,Int32&amp;gt;(c =&amp;gt; c.OrderID, (c, v) =&amp;gt; c.OrderID = v, &lt;span class="str"&gt;&amp;quot;OrderID&amp;quot;&lt;/span&gt;);
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataKeyProperty&amp;lt;OrderDetail,Int32&amp;gt; ProductIDProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataKeyProperty&amp;lt;OrderDetail,Int32&amp;gt;(c =&amp;gt; c.ProductID, (c, v) =&amp;gt; c.ProductID = v, &lt;span class="str"&gt;&amp;quot;ProductID&amp;quot;&lt;/span&gt;);
    &lt;span class="rem"&gt;// non-key properties&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Decimal&amp;gt; UnitPriceProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Decimal&amp;gt;(c =&amp;gt; c.UnitPrice, (c, v) =&amp;gt; c.UnitPrice = v, &lt;span class="str"&gt;&amp;quot;UnitPrice&amp;quot;&lt;/span&gt;);
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Int16&amp;gt; QuantityProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Int16&amp;gt;(c =&amp;gt; c.Quantity, (c, v) =&amp;gt; c.Quantity = v, &lt;span class="str"&gt;&amp;quot;Quantity&amp;quot;&lt;/span&gt;);
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Single&amp;gt; DiscountProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataProperty&amp;lt;OrderDetail,Data,Single&amp;gt;(c =&amp;gt; c.Discount, (c, v) =&amp;gt; c.Discount = v, &lt;span class="str"&gt;&amp;quot;Discount&amp;quot;&lt;/span&gt;);
    &lt;span class="rem"&gt;// references&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataRefProperty&amp;lt;OrderDetail,Data,Order&amp;gt; OrderProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataRefProperty&amp;lt;OrderDetail,Data,Order&amp;gt;(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel.Order_Details_Order&amp;quot;&lt;/span&gt;,&lt;span class="str"&gt;&amp;quot;Order&amp;quot;&lt;/span&gt;,&lt;span class="str"&gt;&amp;quot;Order&amp;quot;&lt;/span&gt;);
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataRefProperty&amp;lt;OrderDetail,Data,Product&amp;gt; ProductProperty = 
                  &lt;span class="kwrd"&gt;new&lt;/span&gt; DataRefProperty&amp;lt;OrderDetail,Data,Product&amp;gt;(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel.Order_Details_Product&amp;quot;&lt;/span&gt;,&lt;span class="str"&gt;&amp;quot;Product&amp;quot;&lt;/span&gt;,&lt;span class="str"&gt;&amp;quot;Product&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

&lt;h3&gt;Data Properties Explained&lt;/h3&gt;

&lt;p&gt;Each data property is statically initialized in the data class and has two methods: Get() and Set(). &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Get() takes a single argument &amp;#8211; the shell object and returns the property value &lt;/li&gt;

  &lt;li&gt;Set() takes two arguments: shell object and new property value. It sets the property to the value provided. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 4 types of data properties:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Simple properties (DataProperty class) that are responsible for getting and setting non-key, non-navigation properties &lt;/li&gt;

  &lt;li&gt;Key properties (DataKeyProperty) that are responsible for gettings and settings properties that are part of the primary key (the values are stored in the shell class itself) &lt;/li&gt;

  &lt;li&gt;Collection properties (DataCollectionProperty) that manage object collections &lt;/li&gt;

  &lt;li&gt;Reference properties (DataRefProperty) that are responsible for getting and setting reference properties &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple property (implemented in DataProperty.cs) makes sure that the data object has been initialized on-demand and delegates to ObjectContext.Refresh() to fetch object values and relationships. When setting property values, it calls ReportPropertyChanging and ReportPropertyChanged so that object state is properly tracked.&lt;/p&gt;

&lt;p&gt;Key properties do nothing more than calling ReportPropertyChanging/ReportPropertyChanged in addition to getting and setting actual key values in the shell object.&lt;/p&gt;

&lt;p&gt;Collection properties take care of initializing relationships in the RelationshipManager and wrapping the results with LazyEntityCollection&amp;lt;T&amp;gt; for load-on-demand functionality.&lt;/p&gt;

&lt;p&gt;Reference properties are probably the most interesting ones, because they deal with stub objects. Whenever the user navigates a relationship that has not yet been initialized, a new stub object (that is just a shell without data) is created and attached to the object context. There is a little additional complication with handling polymorphic objects, because we need to know the concrete subtype to create based just on the EntityKey, but that is a story for a separate article.&lt;/p&gt;

&lt;h3&gt;Usage&lt;/h3&gt;

&lt;p&gt;Code generation application (EFLazyClassGen project in the sample solution) emits code that is meant to be a drop-in replacement for designer-generated code (namespaces and class names are the same). Just invoke that with two parameters: &lt;/p&gt;

&lt;p&gt;EFLazyClassGen input.[csdl,edmx] output.cs&lt;/p&gt;

&lt;p&gt;Only simple code generation is supported (for example multiple schemas are not) at this point and I&amp;#8217;ve only tested this against NorthwindEF and AdventureWorksXLT schemas. &lt;/p&gt;

&lt;p&gt;Generated classes have public interface similar to one generated by EdmGen - some notable differences are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;EntityKey and EntityState members are not publicly exposed (you can still get to them by casting to IEntityWithKey) &lt;/li&gt;

  &lt;li&gt;Serialization is not supported (no serialization-specific are generated). If you want to serialize lazy objects, you have to do this using DTO (Data Transfer Objects) &lt;/li&gt;

  &lt;li&gt;There is no *Reference property on many-to-one relationships. It means there is no way to control the &amp;quot;loaded&amp;quot; state of related end, but that should not be a problem since everything appears to be loaded. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LazyObjectContext derives from ObjectContext and adds two new events, which can be used to trace the internal workings of EFLazyLoading:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;LazyObjectContext.StubCreated - occurs whenever new stub object is created &lt;/li&gt;

  &lt;li&gt;LazyObjectContext.ObjectLoaded - occurs whenever delayed occurs occurs &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See the samples for more information. There are also new LazyObjectContext methods:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Reset(ILazyEntityObject) - which detaches and releases data object from a shell object - while keeping the object attached to the context. &lt;/li&gt;

  &lt;li&gt;ResetAllUnchangedObjects() - does the same thing for all unchanged objects in the context - objects will be demand-loaded next time any of the properties is accessed. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the ZIP file there is a help file (CHM) which has auto-generated API documentation (using &lt;a href="http://blogs.msdn.com/sandcastle/" target="_blank"&gt;Sandcastle&lt;/a&gt;). I hope this will be useful.&lt;/p&gt;

&lt;h3&gt;Lessons learned&lt;/h3&gt;

&lt;p&gt;The first and foremost lesson learned is that it is quite possible to have transparent lazy loading working with Entity Framework. Being able to write your own entity classes (provided that they adhere to IPOCO specification) that add functionality under the hood opens up a whole new world of possibilities.&lt;/p&gt;

&lt;p&gt;Possible applications of this technique may include cross-ObjectContext object sharing &amp;amp; caching (that may be actually very simple, because you can easily share &amp;#8220;Data&amp;#8221; objects if you can only make them read-only and copy on write).&lt;/p&gt;

&lt;p&gt;In the next post I will explain the object type cache (for managing EntityKey to concrete type mapping) and introduce additional extension methods that make it possible to write LINQ and Entity SQL queries that return stubs of objects.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8496771" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jkowalski/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx">EFLazyLoading</category></item><item><title>Transparent Lazy Loading for Entity Framework – part 1</title><link>http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx</link><pubDate>Mon, 12 May 2008 19:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8495183</guid><dc:creator>jkowalski</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/jkowalski/comments/8495183.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jkowalski/commentrss.aspx?PostID=8495183</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jkowalski/rsscomments.aspx?PostID=8495183</wfw:comment><description>&lt;p&gt;This post is a part of the series that describes &lt;a href="http://code.msdn.microsoft.com/EFLazyLoading" target="_blank"&gt;EFLazyLoading&lt;/a&gt; library.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx" target="_blank"&gt;Part 1 - Strategies for implementing lazy loading&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx" target="_blank"&gt;Part 2 - Implementation of EFLazyLoading&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/28/transparent-lazy-loading-for-entity-framework-part-3-anatomy-of-a-stub.aspx" target="_blank"&gt;Part 3 - Anatomy of a Stub&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The first release of Entity Framework supports explicit loading. This means that if you are navigating a relationship, you have to make sure it is loaded by explicitly calling Load()on &lt;a href="http://msdn.microsoft.com/en-us/library/bb297956.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb297956.aspx"&gt;EntityReference&amp;lt;T&amp;gt;&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/bb354106.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb354106.aspx"&gt;EntityCollection&amp;lt;T&amp;gt;&lt;/a&gt; objects, or pre-loading your relationships by using &lt;a href="http://msdn.microsoft.com/en-us/library/bb738708.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb738708.aspx"&gt;Include()&lt;/a&gt; on your query.&lt;/p&gt;  &lt;p&gt;If you try to navigate a many-to-one or one-to-one relationship that is not loaded, you will get a NullReferenceException. In case of EntityCollection&amp;lt;T&amp;gt; that has not been loaded you will silently get an empty collection which may lead to subtle bugs.&lt;/p&gt;  &lt;p&gt;One of the benefits of explicit loading is that you can easily locate all places in your code that cause database round-trips. Unfortunately general-purpose code that can be used in multiple units of work (such as validation, permission checks, etc.) does not typically know which relationships have been loaded. Because of that it always has to check whether the relationship being navigated has been loaded, and call Load() if not. &lt;/p&gt;  &lt;p&gt;As you can imagine this can easily lead to code that is cluttered with IsLoaded/Load():&lt;/p&gt;  &lt;pre class="csharpcode"&gt;var prod = entities.Products.First();
prod.SupplierReference.Load();
var supplier = prod.Supplier;
prod.OrderDetails.Load();
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (OrderDetail det &lt;span class="kwrd"&gt;in&lt;/span&gt; prod.OrderDetails)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!det.OrderReference.IsLoaded)
        det.OrderReference.Load();
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0} {1}&amp;quot;&lt;/span&gt;, det.Product.ProductName, det.Order.OrderDate);
}&lt;/pre&gt;

&lt;p&gt;Transparent lazy loading is a way to make your business logic code more readable by handling loads under the hood. As a result you get an illusion of a fully populated object graph, so the above example can be re-written as:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;var prod = entities.Products.First();
var supplier = prod.Supplier;
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (OrderDetail det &lt;span class="kwrd"&gt;in&lt;/span&gt; prod.OrderDetails)
{
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;{0} {1}&amp;quot;&lt;/span&gt;, det.Product.ProductName, det.Order.OrderDate);
}&lt;/pre&gt;

&lt;p&gt;This simplicity comes at a cost:&lt;/p&gt;

&lt;p&gt;- Database queries are more difficult to locate (potentially any relationship navigation can lead to a query)&lt;/p&gt;

&lt;p&gt;- Object graph is fully populated so you cannot easily serialize parts of it without using DTO (Data Transfer Objects). Carelessly returning an object from a web service could potentially bring in the entire database with it.&lt;/p&gt;

&lt;p&gt;As we said, Entity Framework v1 supports explicit loading only, but the object layer code is something the developer can control, either by writing it by hand or creating a tool to do so. We just need to inject Load() method call in a few places. Sounds simple?&lt;/p&gt;

&lt;h3&gt;Strategies for implementing transparent lazy loading&lt;/h3&gt;

&lt;p&gt;There are two main strategies when implementing transparent lazy loading. One approach is to fully materialize related objects whenever you access them &amp;#8211; let&amp;#8217;s call this approach Lazy Initialization.&lt;/p&gt;

&lt;p&gt;Lazy Initialization is easy do in Entity Framework &amp;#8211; all you have to do is to add extra code to do Load() in property getters that are used to navigate relationships (see &lt;a href="http://blogs.msdn.com/dsimmons/archive/2007/09/01/ef-codegen-events-for-fun-and-profit-aka-how-to-add-custom-attributes-to-my-generated-classes.aspx" mce_href="http://blogs.msdn.com/dsimmons/archive/2007/09/01/ef-codegen-events-for-fun-and-profit-aka-how-to-add-custom-attributes-to-my-generated-classes.aspx"&gt;Danny&amp;#8217;s post about codegen events&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The following code checks whether the relationship has been loaded and forces Load() if it has not &amp;#8211; this frees the business logic to focus on business rules rather than plumbing (note that this source code change only works with attached objects &amp;#8211; detached objects require special handling &amp;#8211; not shown here):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[EdmRelationshipNavigationProperty(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Products_Supplier&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Supplier&amp;quot;&lt;/span&gt;)]
[XmlIgnore]
[SoapIgnore]
[DataMember]
&lt;span class="kwrd"&gt;public&lt;/span&gt; Supplier Supplier
{
    get
    {
        &lt;span class="rem"&gt;// added code &lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!SupplierReference.IsLoaded)
            SupplierReference.Load();
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ((IEntityWithRelationships)(&lt;span class="kwrd"&gt;this&lt;/span&gt;)).RelationshipManager.
            GetRelatedReference&amp;lt;Supplier&amp;gt;(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel.Products_Supplier&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Supplier&amp;quot;&lt;/span&gt;).Value;
    }
    set
    {
        ((IEntityWithRelationships)(&lt;span class="kwrd"&gt;this&lt;/span&gt;)).RelationshipManager.
            GetRelatedReference&amp;lt;Supplier&amp;gt;(&lt;span class="str"&gt;&amp;quot;NorthwindEFModel.Products_Supplier&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Supplier&amp;quot;&lt;/span&gt;).Value = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;The result is that product.Supplier is always accessible, which is what we wanted. Unfortunately fully materializing related objects is not always desirable for performance reasons. There are cases where you do not care about related object attributes, but the object itself is interesting to you. Consider an example function ShareManager that returns true when two employees share the same manager and false otherwise:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;bool&lt;/span&gt; ShareManager(Employee emp1, Employee emp2)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (emp1.Manager == emp2.Manager)
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;By merely touching emp1.Manager and emp2.Manager, we have potentially caused two Manager entities to materialize (and that means two database queries), while we were just interested in checking whether they are the same object. &lt;/p&gt;

&lt;p&gt;In Entity Framework you can reason about identities of related objects without materializing them by examining EntityKey property on EntityReference&amp;lt;T&amp;gt;. So our example can be re-written for performance as:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;bool&lt;/span&gt; ShareManager(Employee emp1, Employee emp2)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (emp1.ManagerReference.EntityKey == emp2.ManagerReference.EntityKey)
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p mce_keep="true"&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;But that is not nearly as nice as the first code snippet because you have to deal with EntityKeys now.&lt;/p&gt;

&lt;p&gt;Fortunately it turns out that with some clever code generation it is possible to have the first syntax and not pay the price for object materialization except when it is absolutely needed. Intrigued? Stay tuned for Part 2 where I will introduce a lazy loading framework (code generator and supporting library) for EF. &lt;/p&gt;

&lt;p&gt;The strategy that will be used is based on an observation that you do not need to materialize an object if you do not access its non-key properties&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updates&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;The code for EFLazyLoading library can be downloaded from &lt;a href="http://code.msdn.microsoft.com/EFLazyLoading"&gt;http://code.msdn.microsoft.com/EFLazyLoading&lt;/a&gt;

  &lt;br /&gt;The second part of this article is available &lt;span style="font-size: 11pt; font-family: &amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: &amp;#39;Times New Roman&amp;#39;; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;&lt;a href="http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-2.aspx"&gt;here&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8495183" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jkowalski/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/jkowalski/archive/tags/EFLazyLoading/default.aspx">EFLazyLoading</category></item></channel></rss>