title: Read the value of a referenced entity's PropertyInfo using EF4
body: <p>I would like to dynamically read the values of the PropertyInfos of EntityObjects that I come across when looping through the PropertyInfos of a parent entity (the column values of the instance of ImageType that is connected to the current instance of Image, f.i.).</p>
  
  <p>The main entity's type is only known at runtime, so I'm looking for a generic way of reading the PropertyInfo values of any referenced entity object.</p>
  
  <p>I can loop through the PropertyInfos of the sub entity, but when I try to get a value I get a TargetException: Object does not match target type.</p>
  
  <pre><code>// loop through the main entity's properties
  foreach (PropertyInfo pi in entityType.GetProperties())
  {
      // if the main entity's property is an entity
      if (pi.PropertyType.BaseType == typeof(System.Data.Objects.DataClasses.EntityObject))
      {
          // loop through the sub entity's properties
          foreach(PropertyInfo mychildren in pi.PropertyType.GetProperties())     
          {   
              // the loop works fine but when i try to get a value I get a
              // TargetException: Object does not match target type.
              object test = mychildren.GetValue(pi, null);
          }
      }
  }
  </code></pre>
  
  <p>How can I do this?</p>
  
  <p><strong>Edit</strong>:</p>
  
  <p>Entity Framework 4.0 doesn't seem to allow you to dynamically retrieve the instances of an entity's related entities. But with EF 4.1 and up you can, by using their class name as a string identifier. So I upgraded to EF 4.2 and got it working.</p>
  
  <p>The reason I wanted this code is to use it in my DTO translation routine. My DTO's can have string properties that correspond to the name properties of related entities and this way I can access those without having to hard code the related entities' types.</p>
  
  <p>In EF 4.1 and up, the ObjectContext is wrapped by a class named DbContext, which provides navigational properties with which to get instances of related entities using strings. To dynamically retrieve a singular related entity, you can use: </p>
  
  <p>dynamic refObject = Activator.CreateInstance(refObjectType);</p>
  
  <p>refObject = context.Entry(currentObject).Reference(refObjectType.Name).CurrentValue;</p>
  
  <p>For those upgrading from 4.0: The recommended way to work with DbContext is not with EntityObjects but with POCOs. These can be made manually or they can be generated via the edmx context menu.</p>
  
  <p>My current implementation is as follows:</p>
  
  <pre><code>// Loop through the propertyinfos of the dto's type
  foreach (PropertyInfo pf in dtoType.GetProperties().Where(p =&gt; p.CanWrite))
  {
      // Use the name of the dto property to get the corresponding property from the POCO's type. If it doesn't exist, pi will be null
      PropertyInfo pi = pocoType.GetProperty(pf.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
  
      if (pi != null)
      {
          // Check if the current propertyinfo of the POCO has a subproperty named Id
          // If this is the case we treat the propertyinfo as a referenced POCO
          if (pi.PropertyType.GetProperty("Id") != null)
          {
              // skip referenced POCOs if their data is not needed
              if (!includeRelated) continue;
  
              // Get the type of the referenced POCO
              Type refObjectType = pi.PropertyType;
              // Create an instance of the referenced POCO
              dynamic refObject = Activator.CreateInstance(refObjectType);
  
              // Create a type of GenericRepository&lt;objectType&gt;
              Type refObjectRepositoryType = typeof(GenericRepository&lt;&gt;).MakeGenericType(refObjectType);
              // Create an instance of GenericRepository&lt;objectType&gt;
              dynamic refObjectRepository = Activator.CreateInstance(refObjectRepositoryType);
  
              // Fill the dynamic POCO instance with the values of the referenced POCO instance
              refObject = refObjectRepository._context.Entry(poco).Reference(refObjectType.Name).CurrentValue;
  
              try
              {
                  // Set the dto property with the name value of the referenced POCO instance
                  // (i.e. dtoImage.ImageType = pocImage.ImageType.Name)
                  pf.SetValue(dto, refObject.Name, null);
              }
              catch (RuntimeBinderException)
              {
                  // this happens when the related entity is null, ie. in one to zero-or-one relationships
                  continue;
              }
  
              continue;
          }
  
          // If the propertyinfo's propertytype does not have an Id property, just set the value of  
          // the dto property to that of the POCO's propertyinfo directly
          pf.SetValue(dto, pi.GetValue(poco, null), null);
  
      }
  }
  </code></pre>
  
  <p>For now this code will only work for referenced entities that have both an Id and a Name property. Also, there is likely to be a performance penalty for this approach so I have implemented the flag includeRelated to toggle whether to query the related objects or not.</p>