BjarkeCK
BjarkeCK

Reputation: 5729

MVC dealing with multiple LINQ Queries in a single View

Now, I realize that this question has been answered before, but I just can't warp my head around it and make it work in my example:

View
should contain 2 foreach loops fx
foreach(var item in Model.ListA)
foreach(var item in Model.ListB)

Model
should contain a class with a LinqDataContext object and two properties: (ListA and ListB)

Controller
should pass the Model through the View.


How would the Model and Controller look to achieve this? Some simple code examples would be really helpful :)

Upvotes: 0

Views: 2923

Answers (3)

Michael Stum
Michael Stum

Reputation: 180944

Whoa, padding a LinqDataContext to a View smells pretty bad. Why would you do that?

The controller should get all the data that it needs either from said LinqDataContext or from a backend service and then create a simple ViewModel that only contains an IList or IEnumerable.

public class YourViewModel 
{
    public List<A> ListA {get; set;}
    public List<B> ListB {get; set;}
}

public ActionResult YourControllerAction()
{
   var context = yourDataContext;

   var model = new YourViewModel
   {
      ListA = context.TableA.Where(x => x.Something)
                     .Select(x => x.ConvertSqlToBusinessObject()).ToList(),
      ListB = context.TableB.Where(x => x.Something)
                     .Select(x => x.ConvertSqlToBusinessObject()).ToList()
   };

   return View("Index",model);
}

Upvotes: 1

Heather
Heather

Reputation: 2652

I would add a small addition to the previous answers: The controller should implement the logic necessary to select the proper view and view model, however it should NOT populate the View Model. The view model is perfectly capable of populating itself.

This pattern improves the encapsulation of both the controller and view model as well as creating a cleaner demarcation between concerns. Thus, if I steal Michael's code snippet:

In the controller

public ActionResult YourControllerAction(){
   MyDbContext context = new MyDbContext();
   return View("YourControllerAction", new YourViewModel(context));
}

In the view model

public class YourControllerAction {
    public YourControllerAction(MyDbContext context) {
         ListA = context.TableA.Where(x => x.Something).Select(x => x.ConvertSqlToBusinessObject()).ToList();
         ListB = context.TableB.Where(x => x.Something).Select(x => x.ConvertSqlToBusinessObject()).ToList();
    }
}

Upvotes: 0

scottm
scottm

Reputation: 28701

You've got it a bit backward. Your data context should be in the controller (preferably in a layer even lower that the controller uses). You always want your controller responsible for getting/updating data, and populating the model. Then, the model is delivered to the view with everything needed for the presentation of that data.

public class MyModel
{
    public List<ListAEntity> ListA {get;set;}
    public List<ListBEntity> ListB {get;set;}
}


public class HomeController : Controller
{
    private readonly MyDataContext _context = new MyDataContext();

    public ActionResult Index()
    {
        var model = new MyModel()
        {
            ListA = _context.Get<ListAEntity>().ToList(),
            ListB = _context.Get<ListBEntity>().ToList()
        };

        return View(model);
    }
}

Upvotes: 1

Related Questions