0

This question is part B of my other question here:

Inefficient MVC ViewModel Making Multiple Calls to the Database?

I knew multiple calls to the db was a bad idea. But, I guess my real question is if I use my last chunk of code or speti43's example let's say like this in my model constructor to eliminate multiple db calls:

    Public Class OrdersSummary{
    ...
      Public ???? GetOrders(){

        var ordersInMemory = orders.ToList();
        decimal? GrossProfitTotal = ordersInMemory.Sum(s => s.Profit);
        decimal? CommissionTotal = ordersInMemory.Sum(s => s.Commission);
        decimal? NetProfitTotal = GrossProfitTotal + CommissionTotal;
        return ?????

      }
    }

How do I pass those seperate but similar pieces of data to the controller? I was trying to use a tuple like this based on some other SO article recommendation here:

How to return multiple values from a function in C# (ASP.NET)?

public Tuple<IEnumerable<dynamic>, decimal?, decimal?, decimal?> GetOrders(string sortOrder, string searchString)
{
...

    return new Tuple<IEnumerable<dynamic>,decimal?,decimal?,decimal?> (ordersInMemory, GrossProfitTotal, CommissionTotal, NetProfitTotal);
}

Does this sound reasonable? Then I have no idea how to reference the tuple in my controller:

        var ordersummary = new OrdersSummary();
        var viewModel = new OrderSummary
        {
            ???? cause I have no idea how to reference the tuple
        };
        return View(viewModel);

The other issue is I'm not entirely sure I'm building the properties correct in my view model. Currently I have it like this for the four pieces of data and then individual properties of the Orders list:

public class OrderSummary
    {
        public IEnumerable<dynamic> Orders { get; set; }
        public decimal GrossProfitTotal { get; set; }
        public decimal CommissionTotal { get; set; }
        public decimal NetProfitTotal { get; set; }

        //Orders Table Properties
        public int OrderNumber { get; set; }
        public DateTime OpenTime { get; set; }
        //more properties here that correspond to the Orders table.
    }

It seems like I might need to structure the tuple properties different in the view model? If so, what syntax?

I think I might know what goes in the View if I knew what goes in the controller. Is this even the correct way to go about it? I got this whole view model structure idea from step 8 on the MVCMUsicStore tutorial:

http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-8

Community
  • 1
  • 1
Sum None
  • 2,164
  • 3
  • 27
  • 32

1 Answers1

0

After much cursing and even more red squiggly lines, I figured out a couple ways to do this and neither involves a tuple:

First Method:

ViewModel:

public IEnumerable<OrderSummary> Orders { get; set; }
public decimal? GrossProfitTotal { get { return Orders.Sum(s => (decimal)s.Profit); } }
public decimal? CommissionTotal { get { return Orders.Sum(s => (decimal)s.Commission); } }
public decimal? NetProfitTotal { get { return GrossProfitTotal + CommissionTotal; } }

Controller:

var orderssummary = new OrdersSummary();
var viewModel = new OrderSummary
{
   Orders = orderssummary.GetOrders(sortOrder, searchString),
}

return View(viewModel);

Second Method:

ViewModel:

public IEnumerable<OrderSummary> Orders { get; set; }        
public decimal? GrossProfitTotal { get; set; }
public decimal? CommissionTotal { get; set; }
public decimal? NetProfitTotal { get; set; }

Controller:

    var orderssummary = new OrdersSummary();
    var orderslist = orderssummary.GetOrders(sortOrder, searchString);

    decimal? grossprofittotal = orderslist.Sum(s => (decimal)s.Profit);
    decimal? commissiontotal = orderslist.Sum(s => (decimal)s.Commission);
    decimal? netprofittotal = orderslist.Sum(s => (decimal)s.Profit + s.Commission);

        var viewModel = new OrderSummary
        {
            Orders = orderslist,
            GrossProfitTotal = grossprofittotal,
            CommissionTotal = commissiontotal,
            NetProfitTotal = netprofittotal,
        };

    return View(viewModel);

View (for first and second methods):

@foreach (var item in Model.Orders){
   @item.OrderNumber
   @item.OpenTime
   etc.
}
    @Model.CommissionTotal
    @Model.GrossProfitTotal
    @Model.NetProfitTotal

I am currently using number 1 as it appears a little cleaner. I believe it is now looping through my Ienumerable for the other values instead of hitting the db for each one? I would love to figure out how to calculate all values on a single loop.

It also appears I don't even really need a viewmodel for number 1, but I'll be adding other pieces of info to the view like chart data, so I will leave my options open.

I'm always interested to know people's thoughts and if they have a preference for either or a whole better way.

Sum None
  • 2,164
  • 3
  • 27
  • 32