Quantcast
Viewing latest article 17
Browse Latest Browse All 132

AutoMapper, ProjectTo() – Static Version

Full source code available here.

I’ve been using AutoMapper for quite a few years, but one of the features that I like the most is the ProjectTo method. When using Entity Framework it lets me reduce the number of fields I query from the database to match the model I want to return to the caller.
For example, I have a Product table in the database and a DTO that represents the Product that looks like this –

public class Product
{
	public int ProductId { get; set; }
	public string Name { get; set; }
	public ProductCategory ProductCategory { get; set; }
	public string Description { get; set; }
	public decimal Price { get; set; }
	public string SKU { get; set; }
	public string Code { get; set; }
}  

But say I wanted to return only the ProductId, Name and Code, I could run a query to return the full Product and the map the results to a model that looks like this –

public class ProductModel
{
	public int ProductId { get; set; }
	public string Name { get; set; }
	public string Code { get; set; }
}

In this scenario, the generated SELECT statement will request all seven fields in product and return them to the application, I then have to them to the ProductModel with the three fields I want.
Here is the SQL produced an executed –

SELECT TOP(@__p_0) [p].[ProductId], [p].[Code], [p].[Description], [p].[Name], [p].[Price], [p].[ProductCategory], [p].[SKU]
FROM [Products] AS [p]
ORDER BY [p].[ProductId]

Instead of requesting all seven fields the ProjectTo method will examine the model and generate only the SQL needed to return the relevant fields.

Here is the SQL produced –

SELECT TOP(@__p_0) [p].[Code], [p].[Name], [p].[ProductId]
FROM [Products] AS [p]
ORDER BY [p].[ProductId]

And here is how to write the C# code that performs this time saving, energy saving work –

var productModels = _salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>();

To get this to work you need to do some wiring up.
First add the nuget package AutoMapper.Extensions.Microsoft.DependencyInjection v6.1.1 to your project.

Then create a mapping profile, for this scenario it is very simple. The below code maps Product to ProductModel.

public class MappingProfile : Profile
{
	public MappingProfile()
	{
		CreateMap<Product, ProductModel>();
	}
}

In starup.cs add a call to Mapper.Initialize as shown here.

public void ConfigureServices(IServiceCollection services)
{
	Mapper.Initialize(cfg => {
		cfg.AddProfile<MappingProfile>();
	});

That’s all you need, but that’s not the end of the story…

This approach works with AutoMapper.Extensions.Microsoft.DependencyInjection up to v6.1.1, and AutoMapper v8.1.1, but if you move to newer versions you need a slightly different approach because the static API has been removed.

I’ll show that in the next blog post.

Full source code available here.


Viewing latest article 17
Browse Latest Browse All 132

Trending Articles