Free Tool: Automapping LINQ-to-Entities Queries

Moving property values from one object to another can be tricky; DevTrends has a set of extensions that can help.

In a recent C# Corner column Patrick Steele discussed AutoMapper, which is a fabulous tool. However, AutoMapper has one deficiency when used with LINQ queries.

Let's say you want to return some customer data from your application to some client. It's a bad idea to return Entity Framework objects and, besides, it's an unusual case where the data required by the client is a one-to-one match with your business entities. In fact, in most cases you need a Data Transfer Object that returns some data from several business entities. As an example, assume that you need this DTO to return three pieces of Customer data and the number of Orders for that customer:

Public Class CustomerDTO
  Public Property CustomerID As String
  Public Property ContactName As String
  Public Property City As String
  Public Property OrdersCount As Integer
End Class

You could write code like this to extract the data and initialize a set of CustomerDTOs:

Dim oc As New NorthwindEntities()
Dim custDTOs = From cust In oc.Customers
               Where cust.CustomerID = "ALFKI"
               Select New CustomerDTO With 
                    {.CustomerID = cust.CustomerID,
                     .ContactName = cust.ContactName,
                     .City = cust.City,
                     .OrdersCount = cust.Orders.Count}

The code that moves the data from the Customer object to the DTO is boring to write and, quite frankly, error prone (you know that you're going to use Copy-and-Paste to generate all but the first line and there's a very good chance you'll get end up getting at least one of the lines wrong).

This is where AutoMapper comes in. AutoMapper moves values in properties from one object (typically, a business entity) to another object (typically, a Data Transfer Object or DTO) or vice-versa, often in one line of code. By default, AutoMapper does this by property name, as you'll notice that my code does: City on the Customer object goes to City on the DTO; Orders.Count on the Customer object goes to OrdersCount on the DTO. So AutoMapper will work great, except for that deficiency I mentioned.

When used with a LINQ-to-Entities statement, AutoMapper works its magic after the SQL statement is generated and your data is retrieved. This means that my LINQ statement will cause all the columns in the Customer table to be retrieved in order to move just the four required properties to the DTO. This is a problem Jimmy Bogard, who developer AutoMapper, recognizes, has a workaround for, and is considering as an enhancement to AutoMapper.

In the meantime, DevTrends (a UK consultancy) has provided a set of extensions that does some of what AutoMapper does and avoids this problem. Their Project and To extension methods work together to determine which fields are required by the DTO, and ensure that the SQL statement generated by LINQ retrieves only those columns. The syntax is simple -- this example retrieves only the columns specified by the CustomerDTO class passed to the To method:

Dim oc As New NorthwindEntities()
Dim custDTOs = (From cust In oc.Customers
                Where cust.CustomerID = "ALFKI"
                Select cust).Project.To(Of CustomerDTO)()
DevTrends' extensions don't have all the functionality that AutoMapper does (and that Patrick described in his column). But if you don't need that functionality and do want to speed up your data access, you should pick up DevTrends code.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Copilot AI Billing Shock Met with Meters, Caps and Token-Saving Tools

    GitHub is layering spending limits, expanded credit allowances and increasingly granular usage reporting onto Copilot, while Microsoft is reworking Visual Studio and VS Code to expose -- and reduce -- the cost of agentic development.

  • The AI-Powered Software Development Lifecycle

    René van Osnabrugge makes the case that AI's biggest opportunity in software development is not faster coding -- it's reducing the friction everywhere else in the SDLC.

  • Copilot Usage-Based Billing Gets a Token Dashboard

    Microsoft is keeping Visual Studio's new built-in Agent Skills switched off by default while a public dashboard measures whether their performance gains justify the additional tokens they may consume.

  • VS Code 1.129 Introduces Agent Host and Experimental Agents Window Editor

    Visual Studio Code 1.129 adds a dedicated process for running AI agent sessions and an experimental docked editor for reviewing agent-generated changes.

Subscribe on YouTube