Wednesday, January 29, 2014

AutoMapper Mapping performance comparison

         Currently Automapper is playing a major role in mapping DTO into Business object or vice versa. Likewise I planned to utilize his DynamicMap method to map  DataReader value into DTO object, since it will reduce multiple lines of code to retrieve field ordinal and the lot of un-boxing method calls to retrieve the value from DataReader based on ordinal. However I bit worried about the performance of the DynamicMap method, so to analyze the created a sample program to evaluate the performance of manual and DynamicMap
Created a employee class with 6 different types of fields to check the performance of mapping 1000 records by Automapper and manual mapping
public class Employee
{
       public string Name { set; get; }
       public int Id { set; get; }
       public string Address1 { get; set; }
       public string Address2 { get; set; }
       public DateTime DateOfBirth { get; set; }
       public long Wage { get; set; }
}
The following manual mapping is taking 00:00:00.0020151 time to map the records into DTO from DataReader
private static void MapReaderIntoDTOObject(DataTableReader reader, List<Employee> employees)
        {
            while (reader.Read())
            {
                var employee = new Employee()
                               {
                                   Name = reader.GetString(0),
                                   Address1 = reader.GetString(2),
                                   Address2 = reader.GetString(3),
                                   DateOfBirth = reader.GetDateTime(4),
                                   Wage = reader.GetInt64(5),
                                   Id = reader.GetInt32(1)
                               };
                employees.Add(employee);
            }
        }
However in background the same lines of code are executing for 1000 times
image
Replaced the same mapping with AutoMapper.DynamicMap method, however found the execution time  00:00:00.0230023 is bit higher than manual, but as mentioned it will have single to map the entire values
  employees.AddRange(AutoMapper.Mapper.DynamicMap<DbDataReader, IList<Employee>>(reader));
image
Also did the comparison of AutoMapper.Map (since in our business layer we are using to map DTO to BO and vice versa) with manual mapping it is also bit slower than manual mapping.

image
The overall execution time of each mapping is (it will be vary on each run based on system load)
Manual Mapping Of DataReader into DTO objects: 00:00:00.0020151
AutoMapper Mapping of DataReader into DTO objects: 00:00:00.0230023
Manual Mapping of Object to DTO objects: 00:00:00.0010004
AutoMapper Mapping  of Object into DTO objects: 00:00:00.0030005
The time difference in between manual and DynamicMapping mapping is 0.0209872, I felt it is acceptable one when compare to the manual mapping with AutoMapper.Map (Also it will reduce lot of manual process, like getting ordinal, conditional check to assign default value, etc.,).
Sample source can be found in this link.

Thursday, May 2, 2013

Thursday, April 5, 2012

How to effectively use Automapper with DbContext/Entity Framework

Generally the AutoMapper is used to map the field values in between  Business and DTO objects/viceversa in irrespective of types. To speed up my development used the AutoMapper for map the Entity to POCO object. In Later stage i feel the automapper is neglecting the lazy loading of Entity Framework, since by default AutoMapper will map the Fields based on the naming convention. Ex: Having the EF structure like below



Retrieved the Customer object from context and mapped it to POCO trainer object to use in UI/BO layer.

 customer = AutoMapper.
Mapper.Map<Common.Customer, Data.Model.Customer>(dbCustomer);

 The AutoMapper implicitly map the customer along with its down level child objects. ie: it map the user, customernutrition, etc. To avoid this I have added a extension method and ignore the properties which are belongs Common namspace.

public static IMappingExpression<TSource, TDestination> IgnoreSynsObjects<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{var flags = BindingFlags.Public | BindingFlags.Instance;
var sourceType = typeof(TSource);
var destinationProperties = typeof(TDestination).GetProperties(flags);
foreach (var property in destinationProperties)
{if (property.PropertyType.FullName.Contains("SYNS.Common.")
||property.PropertyType.FullName.Contains("SYNS.Common.TrackableCollection"))
{
expression.ForMember(property.Name, opt => opt.Ignore());
}
}return expression;
}

And the mapping should be as

AutoMapper.Mapper.CreateMap<Data.Model.Customer, Common.Customer>().IgnoreAllNonExisting();


The instance mapping should be as like follow


customer = AutoMapper.Mapper.Map(customer, dbCustomer);

After this change, the lazyloading is not neglected by the Automapper.

Monday, March 26, 2012

Way to resolve Unit Test Adapter threw exception in Visual Studio

I tried to execute the unit test with code coverage option, unfortunately it throws following exception


Unit Test Adapter threw exception:
Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information..

On analysis found that the Code Coverage Settings file is pointing the wrong re-singing key file. I have point this to the correct path, after this change able to run the unit test with code coverage. The Steps are


Edit the test settings



In "Data and Diagnostics" option, double click "Code Coverage".

Point the correct snk file, then you can able to run the unit test with code coverage.