title: AutoMapper use for simple Entity Properties to SqlParameters array
body: <p>I've begun looking into AutoMapper and have a 'data driven' scenario... I have the code for populating entity properties from a SqlDataReader based on some 'schema information' I pass around...</p>
  
  <p>Next I want to take Entity properties... and then based on the Schema information I have, create a set of SqlParameters from the entity values...</p>
  
  <p>Perfect job for AutoMapper... but I see a lot of flattening from Object graph to Object graph but no simple samples for this task...   When going at it, I've stumbled a bit with some of the nuances but have a rough idea of what I should be doing...</p>
  
  <p>I've drafted up the following... I'm trying to use the TypeConverters and registering them in advance, but when I execute the actual map.ForMember() operation it throws an error complaining</p>
  
  <p>"Custom configuration for members is only supported for top-level individual members on a type."</p>
  
  <p>A few variations I have tried and not been successfull with...</p>
  
  <p>(1) tried far simpler versions...
  (2) tried using the ConstructUsing() mechanism and then the target of the operation is actually the SqlParameter.[[[Value]]] property (most likely the 'right' way in the AutoMapper mindset right??)
  (3) tried pre-establishing the target list and then 'finding' the matching parameter - but setting the .Value on it was still a missing part of that equation...</p>
  
  <p>Being new to AutoMapper I expected a few challenges but I've spent enough time on this and not found anything obvious... seems like it should be a simple use-case for the framework...  I must be missing something obvious...</p>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          // Drive it by some data... Say some mapping info we have from elsewhere...
          var myMappingPairs = new List&lt;MyMappingInfo&gt;()
          {
              new MyMappingInfo() { PropertyName = "MyGuidProperty", ParameterName = "Param00" },
              new MyMappingInfo() { PropertyName = "MyStringProperty", ParameterName = "Param01" },
              new MyMappingInfo() { PropertyName = "MyInt16Property", ParameterName = "Param02" },
              new MyMappingInfo() { PropertyName = "MyInt32Property", ParameterName = "Param03" },
              new MyMappingInfo() { PropertyName = "MyInt64Property", ParameterName = "Param04" }
          };
  
          // We can try to register these, but the sytax isn't clear to me yet...
          Mapper.CreateMap&lt;Guid, SqlParameter&gt;().ConvertUsing&lt;GuidToSqlParameterConverter&gt;();
          Mapper.CreateMap&lt;String, SqlParameter&gt;().ConvertUsing&lt;StringToSqlParameterConverter&gt;();
          Mapper.CreateMap&lt;Int16, SqlParameter&gt;().ConvertUsing&lt;Int16ToSqlParameterConverter&gt;();
          Mapper.CreateMap&lt;Int32, SqlParameter&gt;().ConvertUsing&lt;Int32ToSqlParameterConverter&gt;();
          Mapper.CreateMap&lt;Int64, SqlParameter&gt;().ConvertUsing&lt;Int64ToSqlParameterConverter&gt;();
  
          // Next we'll build our mapping from the "pairings"...
          var map = Mapper.CreateMap&lt;MySourceEntity, List&lt;SqlParameter&gt;&gt;();
  
          foreach (var mappingPair in myMappingPairs)
          {
              map.ForMember
                  (
                      destination =&gt; destination,
                      options =&gt; options.ResolveUsing&lt;PropertyNameResolver&gt;().FromMember
                          (
                              mappingPair.PropertyName    // &lt;-- Data Driven Property Name...
                          )
                  );
          }
  
          // Create a test entity...
          var entity = new MySourceEntity() 
          {
              MyGuidProperty = Guid.NewGuid(), 
              MyStringProperty = "Hello AutoMapper",
              MyInt16Property = Int16.MaxValue,
              MyInt32Property = Int32.MaxValue,
              MyInt64Property = Int64.MaxValue
          };
  
          // Map it...
          var values = Mapper.Map&lt;MySourceEntity, object[]&gt;
              (
                  entity
              );
  
      }
  }
  
  public class MySourceEntity
  {
      public string MyStringProperty { get; set; }
      public DateTime? MyDateTimeProperty { get; set; }
      public Byte? MyByteProperty { get; set; }
      public Int16? MyInt16Property { get; set; }
      public Int32? MyInt32Property { get; set; }
      public Int64? MyInt64Property { get; set; }
      public Guid? MyGuidProperty { get; set; }
  
      public List&lt;String&gt; ThisShouldntGetMapped { get; set; }
      public StringBuilder NorShouldThis { get; set; }
  }
  
  public class MyMappingInfo
  {
      public String PropertyName { get; set; }
      public String ParameterName { get; set; }
      public SqlDbType SqlDbType { get; set; }
  }
  
  public class GuidToSqlParameterConverter : AutoMapper.ITypeConverter&lt;Guid, SqlParameter&gt;
  {
      public SqlParameter Convert(ResolutionContext context)
      {
          if (context.IsSourceValueNull)
          {
              return new SqlParameter()
              {
                  ParameterName = "GuidParam",
                  SqlDbType = SqlDbType.UniqueIdentifier,
                  Value = DBNull.Value
              };
          }
          else
          {
              return new SqlParameter()
              {
                  ParameterName = "GuidParam",
                  SqlDbType = SqlDbType.UniqueIdentifier,
                  Value = context.SourceValue
              };
          }
      }
  }
  public class StringToSqlParameterConverter : AutoMapper.ITypeConverter&lt;string, SqlParameter&gt;
  {
      public SqlParameter Convert(ResolutionContext context)
      {
          if (context.IsSourceValueNull)
          {
              return new SqlParameter()
              {
                  ParameterName = "StringParam",
                  SqlDbType = SqlDbType.NVarChar,
                  Value = DBNull.Value
              };
          }
          else
          {
              return new SqlParameter()
              {
                  ParameterName = "StringParam",
                  SqlDbType = SqlDbType.NVarChar,
                  Value = context.SourceValue
              };
          }
      }
  }
  
  public class Int16ToSqlParameterConverter : AutoMapper.ITypeConverter&lt;Int16, SqlParameter&gt;
  {
      public SqlParameter Convert(ResolutionContext context)
      {
          if (context.IsSourceValueNull)
          {
              return new SqlParameter()
              {
                  ParameterName = "Int16Param",
                  SqlDbType = SqlDbType.SmallInt,
                  Value = DBNull.Value
              };
          }
          else
          {
              return new SqlParameter()
              {
                  ParameterName = "Int16Param",
                  SqlDbType = SqlDbType.SmallInt,
                  Value = context.SourceValue
              };
          }
      }
  }
  
  public class Int32ToSqlParameterConverter : AutoMapper.ITypeConverter&lt;Int32, SqlParameter&gt;
  {
      public SqlParameter Convert(ResolutionContext context)
      {
          if (context.IsSourceValueNull)
          {
              return new SqlParameter()
              {
                  ParameterName = "Int32Param",
                  SqlDbType = SqlDbType.Int,
                  Value = DBNull.Value
              };
          }
          else
          {
              return new SqlParameter()
              {
                  ParameterName = "Int32Param",
                  SqlDbType = SqlDbType.Int,
                  Value = context.SourceValue
              };
          }
      }
  }
  
  public class Int64ToSqlParameterConverter : AutoMapper.ITypeConverter&lt;Int64, SqlParameter&gt;
  {
      public SqlParameter Convert(ResolutionContext context)
      {
          if (context.IsSourceValueNull)
          {
              return new SqlParameter()
              {
                  ParameterName = "Int64Param",
                  SqlDbType = SqlDbType.BigInt,
                  Value = DBNull.Value
              };
          }
          else
          {
              return new SqlParameter()
              {
                  ParameterName = "Int64Param",
                  SqlDbType = SqlDbType.BigInt,
                  Value = context.SourceValue
              };
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I would like to know if the resulting runtime code in AutoMapper will be better performing than say:</p>
  
  <pre><code>    static IDictionary&lt;string, object&gt; GetDictionaryFromObject(object obj)
      {
          if (obj == null) return new Dictionary&lt;string, object&gt;();
          return obj.GetType().GetProperties()
                     .ToDictionary(p =&gt; p.Name,
                                   p =&gt; p.GetValue(obj, null) ?? DBNull.Value);
      }  
  </code></pre>
  
  <p>Which is the entire point of using AutoMapper for me... I already knew how to write reflection code... and I could always have looked at a pure reflection based library to get some additional performance gains, but I thought AutoMapper would likely be a two birds - one stone deal...</p>