斯圖亞特的答案很好。但是現在我在思考爲什麼即使依賴AutoMapper。我們可以做這樣的:
public class Products {
public string Name { get; set; }
public ICollection<ProductSize> ProductSizes { get; set; }
public IList<ProductDto> ConvertTo() {
var q = from size in ProductSizes
from package in size.ProductPackages
from price in package.ProductPrices
select new ProductDto
{
Name = this.Name,
UnitSize = size.UnitSize,
ItemsPerPack = package.ItemsPerPack,
Price = price.Price
};
return q.ToList();
}
}
我跑這是一個試驗,沒有AutoMapper需要0.0000768與AutoMapper需要0.0836274:
class Program {
static void Main(string[] args) {
var c = new ProductPackage
{
ProductPrices = new List<ProductPrice> { new ProductPrice() }
};
var p = Enumerable.Range(1, 100000).Select(x =>
new Products
{
Name = "Good Product",
ProductSizes = new List<ProductSize> {
new ProductSize { Name = "Small", UnitSize = 10, ProductPackages = new List<ProductPackage> { c } } }
}).ToList();
Stopwatch w = new Stopwatch();
w.Start();
var dto = p.Select(x => x.ConvertTo());
Console.WriteLine("Without AutoMapper it took: {0}", w.Elapsed);
w.Stop();
DoWithAutoMapper(p);
Console.Read();
}
private static void DoWithAutoMapper(List<Products> p) {
Func<Products, IEnumerable<ProductDto>> conversion = product =>
from size in product.ProductSizes
from package in size.ProductPackages
from price in package.ProductPrices
select new ProductDto
{
Name = product.Name,
UnitSize = size.UnitSize,
ItemsPerPack = package.ItemsPerPack,
Price = price.Price
};
Mapper.Initialize(c => c.CreateMap<Products, IEnumerable<ProductDto>>()
.ConvertUsing(conversion));
Stopwatch w = new Stopwatch();
w.Start();
var products = p;
foreach(var item in p) {
var dtos = Mapper.Map<Products, IEnumerable<ProductDto>>(item);
}
Console.WriteLine("Using AutoMapper it took: {0}", w.Elapsed);
w.Stop();
}
我看到的唯一的缺點是耦合產品到ProductDto。我不確定這是否應該是一個評論。我想這是另一種方法。
完美,那就是訣竅 –