0

I want to add additional data to the view. I want to put it into ViewBag and later iterate it by simple for each like that:

@foreach (var message in ViewBag.Messages) {
    <p>
        @using (Html.BeginForm()) {
            @Html.EditorFor(x => message.contents) 
            <input type="submit" />
        }
    </p>
}

In controller should I state:

ViewBag.Messages = db.Messages.ToList(); //passing List

or just:

ViewBag.Messages = db.Messages; //passing DbSet

Question: Which will work with my loop.

  • 1
    This is opinion-based, try http://codereview.stackexchange.com. Consider [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter), separation of concerns and unit testing. – CodeCaster Aug 25 '14 at 15:01
  • @CodeCaster My question is which will work with my loop. –  Aug 25 '14 at 15:03
  • 2
    @ToWasz Why dont you try them both? – mxmissile Aug 25 '14 at 15:04
  • If you do `ViewBag.Messages = db.Messages;` you may end up disposing your context before the view renders which would break it. Also EF won't materialize the results until your try to iterate over them in the view, which will show connection issues at a weird layer if anything breaks. – siva.k Aug 25 '14 at 15:19

2 Answers2

1

What I would strongly suggest is to NOT use DbSet<T> inside the view.

And to NOT use ViewBag either.

And even to NOT use a foreach either.

I would use a custom ViewModel object and a strongly typed view, something like:

public class MyViewModel
{
    public IList<MessageModel> Messages { get; set; }
}
public class MessageModel
{
    ...
}

@for (int i = 0; i < Model.Messages.Count; i++) {
    <p>
            @Html.EditorFor(x => Model.Messages[i].contents)
    </p>
}

Also I'm not sure why you put your form inside the loop (I removed it in the above example)...

Community
  • 1
  • 1
ken2k
  • 48,145
  • 10
  • 116
  • 176
1

Using DbSet<T> will have deferred execution and the query will be executed the moment it's iterated in foreach. If you use this variable more than once, it will also execute the query more than once.

While using ToList() will execute the query immediately and then save the result as List<T>. The next usage of this variable will just iterate from the list.

Both of them will work in the loop.

Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67