0
votes

I hav been using automapper for sometime trying figure out how to handle different situation. I came across below situation and need some help figuring out the best approach. Below are my EF related classes;

public sealed class Invoice
{
    public int InvoiceID { get; set; }

    public DateTime InvoiceDate { get; set; }

    public string CustomerName { get; set; }

    public string CustomerAddress { get; set; }

    public double? DiscountAmt { get; set; }

    public Transaction InvoiceTransaction { get; set; }

    public int TransactionID { get; set; }

}

public sealed class Transaction
{
    public Transaction()
    {
        this.TransactionItems = new List<TransactionDetail>();
    }

    public int TransactionID { get; set; }

    public DateTime TransactionDate { get; set; }

    public DateTime TransactionLogDate { get; set; }

    public TransactionType TransactionType { get; set; }

    public IList<TransactionDetail> TransactionItems { get; set; }

    public Invoice RefferingInvoice { get; set; }

    public string Remarks { get; set; }
}

public sealed class TransactionDetail
{
    public int TransactionID { get; set; }

    public string ProductItemcode { get; set; }

    public Product Product { get; set; }

    public double Qty
    {
        get
        {
            return Math.Abs(this.StockChangeQty);
        }
    }

    public double StockChangeQty { get; set; }

    public double? UnitPrice { get; set; }
}

public sealed class Product
{
    public Product()
    {
        this.StockTransactions = new List<TransactionDetail>();
    }

    public string ItemCode { get; set; }

    public string ProductName { get; set; }

    public string Manufacturer { get; set; }

    public double UnitPrice { get; set; }

    public IList<TransactionDetail> StockTransactions { get; set; }

    public double Qty
    {
        get
        {
            if (this.StockTransactions.Count == 0)
            {
                return 0;
            }
            else
            {
                return this.StockTransactions.Sum(x => x.StockChangeQty);
            }
        }
    }

    public bool Discontinued { get; set; }

}

These are my view model classes;

public class InvoiceReportViewModel
{
    public InvoiceReportViewModel()
    {
        LineItems = new List<InvoiceReportLineItemViewModel>();
    }

    public int InvoiceID { get; set; }

    public DateTime InvoiceDate { get; set; }

    public string CustomerName { get; set; }

    public string CustomerAddress { get; set; }

    public double? DiscountAmt { get; set; }

    public string Remarks { get; set; }

    public string StringInvoiceNo
    {
        get
        {
            return InvoiceID.ToString("########");
        }
    }

    public IList<InvoiceReportLineItemViewModel> LineItems { get; set; }
}

public class InvoiceReportLineItemViewModel
{
    public string ItemCode { get; set; }

    public string ProductName { get; set; }

    public string Manufacturer { get; set; }

    public double? UnitPrice { get; set; }

    public double Qty { get; set; }

    public double LineTotal
    {
        get
        {
            if (UnitPrice.HasValue)
            {
                return UnitPrice.Value * Qty;
            }
            else
            {
                return 0;
            }
        }
    }
}

My requirement is to convert the Invoice EF object to InvoiceReportViewModel object.

To do this I need to setup the profile. This is where I run into a problem; as it's not straight forward. The only way I see this done is by create my own Resolver by extending TypeConverter and manually doing the conversion by overriding ConvertCore method.

If there another way of getting this done (something with less work)???

Also I feel I could Map TransactionDetails EF class to InvoiceReportLineItemViewModel class by using the Mapper.CreateMap()..ForMember(...
But how can I use the mapper to convert it within the ConvertCore method?

Thanks in advance

1

1 Answers

0
votes

In your case I do not see any requirements to use any custom converters. You can convert Invoice EF object to InvoiceReportViewModel using simple Mapper.CreateMap like following:

     public class InvoiceProfile: Profile
        {
            protected override void Configure()
            {
                Mapper.CreateMap<Invoice, InvoiceReportViewModel>()
                    .ForMember(c => c.CustomerName, op => op.MapFrom(v => v.CustomerName))
                    .ForMember(c => c.DiscountAmt, op => op.MapFrom(v => v.DiscountAmt))
                    .ForMember(c => c.InvoiceDate, op => op.MapFrom(v => v.InvoiceDate))
                    .ForMember(c => c.LineItems, op => op.MapFrom(v => v.InvoiceTransaction.TransactionItems));

                Mapper.CreateMap<TransactionDetail, InvoiceReportLineItemViewModel>()
                    .ForMember(c => c.ProductName, op => op.MapFrom(v => v.Product.ProductName))
                    .ForMember(c => c.Qty, op => op.MapFrom(v => v.Qty))
//and so on;
            }
        }

Do not forget to register "InvoiceProfile"