0

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 :)

3 Answers 3

1

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);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you both! Really helpfull, yah i've bin told a couple of times, sometimes it just irritates me that i can't reuse the queryies when i make them in the Controller!
1

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);
}

3 Comments

Thank you that is brilliant, will look closer! How else am i going to loop through two tables from one view? I could do [[ViewData["linq"] = from c in d... ]] but that wont give me intellesence
How would it look if i where not to use lambda expressions? i dont know how they work yet so i would raither user what i know!
@user scottm essentially has a solution that doesn't use lambda.
0

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();
    }
}

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.