2

I am using DTOs (Data Transfer Objects) to transfer information between the different layers of my application.

What is the best practice when it comes to performance and the way I fill these objects? Should I fill only the minimum required information with different methods from my Data Access Layer?

Let’s say I have the following classes :

public class Order
{
    public int OrderNo;
    public Customer Customer;
    public double Total;
}

public class Customer
{
    public int CustId;
    public string CustName;
    public Country Country;
}

public class Country
{
    public int CountryId;
    public string CountryName;
}

What happens if I need to generate a list of orders containing the OrderNo, CustName and CountryName and in another situation, different information maybe from different tables (or DTOs)? Would it be best to use a flatten DTO with only the required fields or make a query using LINQ?

I hope I make this clear enough.

Thanks for you help!

Edit: What I want to know is if I should fill all the nested objects and not only a part of the attributes of an object.

Jason
  • 4,557
  • 5
  • 31
  • 40
  • Could you clarify the usage of the term "layer" in your question? In general, you use DTO's to transfer data between processes and machines. A layer is often referred to as a logical structuring of your code. For instance, in a web app served from a single machine, it is perfectly OK to have your data access layer return rich business objects instead of DTO's. See [Wikipedia](http://en.wikipedia.org/wiki/Multilayered_architecture) for a starting point on this subject. – Marijn Jan 11 '11 at 12:45
  • @Marijn: I have a simple 3-layer web application containing a presentation, a business logic and a data access layer, but I am using this small application to figure out how to structure a bigger one at our company that contains more than 400 tables and will have a lot of different operations and queries on many of those tables. – Jason Jan 11 '11 at 13:40

2 Answers2

6

I think it's going to depend how widely used your DTOs are and how complex they are. For simple ones as shown there's unlikely to be a significant performance impact in populating all the fields, and it would make it easier to use common mapping code. It'll more of an issue for massive sets of data in complex object graphs.

I'd only worry about flattening objects or doing away with DTOs (assuming they make sense to have at all) if performance really is an issue and you can measure the improvement you'll get by making changes.

With regards to populating DTOs we use both LINQ and AutoMapper extensively in a multi-layer ASP.NET MVC application. AutoMapper is hugely useful when mapping between our business objects and dumb view model objects passed to views. While we do not have the largest DB in the world we have a pretty complex schema and have not really suffered any performance bottlenecks as a result of mapping.

One place where we have seen performance problems is in prematurely evaluated LINQ queries that pull back massive object graphs rather than just what's required. By checking that a 'select new' got executed at the right time I reduced one query pulling 850 MB of data across the network from the DB to 1.3 MB!

Tim Croydon
  • 1,866
  • 1
  • 19
  • 30
3

In my opinion you only need DTO's [see Fowler's definition] if you want to transfer information across machines or processes. For instance: when you want to use your (parts of) business logic in a rich client that communicates to a server, or when you physically separate your data access processing from your business processing. DTO's can also be useful when you want share information between processes on the same machine.

In those cases, I'd create DTO's from business objects using Linq or other custom code. AutoMapper as suggested by @Tim can also be useful.

IMO designing the DTO's is part of designing the remote interface. You don't want any unnecessary information in them, to save processing time and network traffic. This could be a case for "flattening". On the other side, you don't want to make your DTO's smaller at the expense of a more "chatty interface".

Note:

From your question, I get the impression that you want to use DTO's to

transfer information from your data acces layer to your business objects in your business layer

In my opinion this is a non-issue for many, many web applications, where both data access and business logic execute on the same machine, in the same process. You won't need a DTO to retrieve business objects from the database - instead persist your entities directly to and from the database. For this, you can use an ORM tool or custom data access code.

Sharing information between business and presentation layers don't necessarily require DTO's either.

Marijn
  • 10,367
  • 5
  • 59
  • 80
  • interesting related questions: [poco-vs-dto](http://stackoverflow.com/questions/725348/poco-vs-dto) | [what-is-data-transfer-object](http://stackoverflow.com/questions/1051182/what-is-data-transfer-object) interesting: one answer suggests using DTO as model in MVC (I'd call that a view model) – Marijn Jan 11 '11 at 15:00
  • Could you give an example on how to "persist your entities directly to and from the database". Thank you. – Jason Jan 11 '11 at 15:32
  • In .net, I would create a data access layer with [repositories](http://martinfowler.com/eaaCatalog/repository.html) using the ORM tool [NHibernate](http://nhforge.org/). When getting started with NHibernate, [FluentNHibernate](http://fluentnhibernate.org/) is great. – Marijn Jan 11 '11 at 15:50