title: Entity Framework virtual properties and database access for Id properties?
body: <p>I have lot of interrelated entities in a project I'm working on, and I am using WCF to use them in several client applications. I soon realized that I was serializing half the data in the database with every call. I fixed the immediate issue but the system is still making lots of database calls, as my service layer objects iterate through all the nested objects in the data layer in their constructors. Many times this is totally unnecessary, so I started to consider alternatives.</p>
  
  <p>If I specify the Id of my nested property then I don't believe the database call is made unless I access the properties of the nested object.</p>
  
  <pre><code>public class MyDataObject
  {    
      public Guid Id { get; set; }
      public string SomeProperty { get; set; }
      public Guid NestedDataObjectId { get; set; }
      [ForeignKey("NestedDataObjectId")]
      public virtual NestedDataObject NestedDataObject { get; set; }
  }
  </code></pre>
  
  <p>I can then use the constructor of my service object to determine whether to lazy load the nested objects something like this:</p>
  
  <pre><code>public class MyServiceObject
  {
      public MyServiceObject(MyDataObject myDataObject, 
                 bool includeNested = true)
      {
          Id = myDataObject.Id;
          SomeProperty = myDataObject.SomeProperty;
          NestedServiceObjectId = myDataObject.NestedDataObjectId;
          if (includeNested)
              NestedServiceObject = new NestedServiceObject(myDataObject.NestedDataObject,
                  includeNested);
      }
  }
  </code></pre>
  
  <p>Which works OK, except now I have an issue with my mock db context for my unit tests as I have to add the object and the id to each mock <code>DbSet</code> as I changed my service code to use the <code>NestedObjectId</code> property rather than the <code>NestedObject.Id</code> property</p>
  
  <p>So I was wondering if the only virtual property that I accessed was the Id field if it would still make a database call for the whole of the object. Something like</p>
  
  <pre><code>if (includeNested)
  {
      NestedServiceObject = new NestedServiceObject(myDataObject.NestedDataObject);
  }
  else
  {
      NestedServiceObject = new NestedServiceObject(myDataObject.NestedDataObject.Id);
  } 
  </code></pre>
  
  <p>This would solve my problem with my mocks, as the service code would always refer to the <code>NestedObject.Id</code> property and I may well end up doing this no matter what for ease of coding and maintainabilty, but I am curious as to whether or not this is the right approach.</p>