EF and Data Transfer Objects

Brad Zacher
3 min readOct 10, 2015

--

Data Model and DTOs
When I first read about the concept of DTOs (data transfer objects), I thought they were bonkers. Why on earth would I bother to duplicate all my effort and hand write another set of nearly identical classes on top of my pre generated model?
That doesn’t really become clear until you have a look and a play with EF to see what it does, and how it best deals with entities. Entity Framework has a lot of internals which help you do things. Foreign key properties help you tell EF when relationships change.

For example, if I want to add a new task to a work package. Without FK properties, I’d have to first load the work package, then add the task to the package’s collection, then save. With the FK property, I can save a step by just setting WorkPackageId to the correct Id, and saving the new task. It may not sound like much, but in my next post I’ll talk about maintaining the object graph and it’ll all become clear.

Another useful feature is having navigation properties in both directions. This is a neat feature only if you’re using lazy loading, as it gives you options for doing related querying down the line, without having to build the queries yourself, and instead letting EF work it all out.

Now, the problem is that having these FK properties, and having two-way additional navigation properties exposes a lot of the underlying implementation of your database to external parties. Usually they don’t care about it, you don’t want to send it to them. In this instance an external party may be a JavaScript client via an ASP.NET WebAPI, or it may be somebody using a distribution of your library which includes your EF model. Particularly with a WebAPI, you don’t want to expose all this data as when JSON.NET serialises your object, it’ll expand the navigation properties. Which means that you could accidentally trigger extra DB transactions and send a lot of useless data to the client.

There is one fundamental thing that you want when designing an API — flexibility in your database design. However if you don’t use DTOs, you instantly lose that because any change to your database means a change to your EF model, which means a change to the objects that the user is consuming. These objects are supposed to be a fixed point — a contract. Having their design remain stable means that your API can be consumed and new versions can be used without fear of breaking changes. By using DTOs, you can create this fixed contract, remove unnecessary properties, and only expose what you have to expose and what you want to expose.

An additional benefit of having DTOs is that you can write different variations of your DTOs depending on what data you want to expose at a given time, whilst storing all of that data under one table or one relationship in your database.

For example I have two different User DTOs — a simple one which only contains a DB ID, User ID and User’s Full Name, and I have a detailed one which also contains their role, the groups they belong to, etc. When I send a Work Package out, it has a user marked as its creator. When consuming a Work Package, an API doesn’t care about any more than that, so sending the detailed version along would be wasteful. However when someone queries the API for a given user — I send back the detailed version because it’s clear that they want all that user’s data then.

So in conclusion — when designing your entities and database, think about how to design it so that it’s as easy as possible for the data logic to interact with itself, and ignore the considerations of the fixed contract with the consumer of the model. Look to DTOs to abstract away your data model and to setup these fixed contracts.

--

--