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 La开发者_开发技巧yer?
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.
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!
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.
精彩评论