2

I am in the habit of using nested loops in classic. Data from the first record set is passed to the second record set. How would I accomplish the same thing in MVC? As far as I can tell, I can only have one model passed to my view.

  <% 
  rs.open "{Call usp_SalesOrder}",oConn
  Do While (NOT rs.EOF)
  %>
    <div><% = rs("SalesOrderNumber")%></div>

    <% 
    rs2.open "{Call usp_SalesOrderLines(" & rs("SOKey") & ")}",oConn
    Do While (NOT rs.EOF)
    %>

      <div><% = rs2("SalesOrderLineNumber")%></div>

    <% 
    rs2.MoveNext
    Loop
    rs2.close
    %>        
  <% 
  rs.MoveNext
  Loop
  rs.close
  %>
2
  • Is this your new code or what you did in classic and wanting to convert over? Commented Mar 5, 2014 at 21:59
  • @RyanSchlueter I'd hope so nested database calls is terribly inefficient, especially when iterating through an ADODB.Recordset. Commented Mar 6, 2014 at 8:39

3 Answers 3

3

My suggestion would be to build a more robust model. It is true that you can only pass one model to your view, but your model can contain the results of multiple data sets, provided you have gathered those data sets in your controller and assigned them to the model.

I also suggest staying away from the ViewBag. It's an easy trap to fall into. Trust me when I say you'll regret it later.

For your example, maybe a model defined like this:

public class MyModel
{
    public List<SalesOrder> SalesOrders = new List<SalesOrder>();
}

public class SalesOrder
{
    public string SOKey = string.Empty;
    public List<SalesOrderLine> SalesOrderLines = new List<SalesOrderLine>();
}

And the code to populate the sales orders in the controller:

public Action Index()
{
    MyModel model = new MyModel();
    model.SalesOrders.AddRange(CallUspSalesOrder());
    foreach (SalesOrder salesOrder in model.SalesOrders)
    {
        salesOrder.SalesOrderLines.AddRange(CallUspSalesOrderLines(salesOrder.SOKey));
    }

    return View(model);
}

That way, you have access to all sales orders (and their sales order lines) within the view.

Sign up to request clarification or add additional context in comments.

Comments

1

I would say that Nathan's post is a good start. Here is what I would do from beginning to end.

This is how I would do my model:

public class SalesOrderModel
{
    public List<SalesOrderLines> SOLines = new List<SalesOrderLines>();
    public List<SalesOrder> SOHeader = new List<SalesOrder>();
}

My Controller would then do this:

public ActionResult Index()
{
        List<SalesOrder> SalesOrder = callSalesOrderUSP.ToList();
        List<SalesOrderLines> SalesOrderLines = new List<SalesOrderLines>();

        foreach (var thing in SalesOrder)
        {
            SalesOrderLines.AddRange(callSalesOrderLinesUSP(thing.SOKey).ToList());
        }

        SalesOrderModel salesOrderModel = new SalesOrderModel
        {
            SOHeader = SalesOrder,
            SOLines = SalesOrderLines
        };



        return View(salesOrderModel);
}

Then in your view you can do this:

@foreach(var something in Model.SOHeader)
{
    foreach (var thing in Model.SOLines.Where(i => i.SOKey == something.SOKey))
    {
        //display info here
    }
}

Comments

0

You can use ViewBag to pass elements not relevant to your model. Also do not be afraid of creating your own ModelView objects that can work between your View and Controller. Your views should not be restricted to what your model has to offer.

Take a look at this for how you can implement a ViewModel in MVC.

And perhaps look at this to see how you can use ViewBag to pass values to your view, not relevant to your model.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.