How to make a LINQ/lambda and consume it in the view?

Asked

Viewed 296 times

5

I have an object called Radio:

public class Radio
{
    public int RadioId { get; set; }
    public string StreamUrl { get; set; }
    public bool Ativo { get; set; }
    public bool Mp3 { get; set; }
}

I’m doing a select on controller and trying to send her to View:

    var RadioAtivo = db.Radios
        .Where(p => p.Ativo == true && p.Mp3 == false)
        .Take(1);

return View(RadioAtivo.ToList());

In the view, would like to recover, for example, the field StreamURL

@model List<RadioFM.Domain.Domain.Radio>

<p>@Html.DisplayFor(r => r.???) </p>

I thought I’d put in a ViewBag, but I found it a bit tricky. I thought of creating a ViewModel already with the data, but I thought it would be kind of duplicate a problem.

What’s the simplest solution in this case?

2 answers

5

It doesn’t make sense here:

var RadioAtivo = db.Radios
    .Where(p => p.Ativo == true && p.Mp3 == false)
    .Take(1);

return View(RadioAtivo.ToList());

If you want to present only one element on screen, first of all, you do not need to use Where() with the Take(). Not that it doesn’t work, but it returns a list, and what you want is just an element.

You must use First() or Single() (if you are sure the element exists) or FirstOrDefault() if you do not have this certainty (the first two give error if there is no element):

var RadioAtivo = db.Radios
    .FirstOrDefault(p => p.Ativo == true && p.Mp3 == false);

The object passed to the return, therefore, it is only an element that does not need to be converted to ToList():

return View(RadioAtivo);

To View, in turn, it doesn’t work with a list, so it doesn’t make sense for you to use it here:

@model List<RadioFM.Domain.Domain.Radio>

@model is for you to say to the View what will be placed inside the variable Model (in capital letters). The correct one is only the class declaration, as below:

@model RadioFM.Domain.Domain.Radio

(an observation: this name of namespace RadioFM.Domain.Domain.Radio has everything to be an anti-standard and therefore a bad practice)

Accordingly, the StreamUrl can be displayed like this:

<p>@Html.DisplayFor(model => model.StreamUrl)</p>

Or still simply so, if there is no formatting configured in the project:

<p>@Model.StreamUrl</p>
  • 1

    perfect, I appreciate the attention as always, it is a project for myself, without commercial objectives, just for learning the MVC.

  • 1

    @Gypsy omorrisonmendez, why RadioFM.Domain.Domain.Radio would be an anti-pattern? I was curious.

  • 1

    @Tobymosque If you have one Class Library calling for RadioFM.Domain, why you need to have a directory Domain inside her? That one Class Library keeps something other than the Domain?

4


The simplest is the one you are doing even. Others form as the ViewBag or create a view model may be useful in certain situations, but are more complex and therefore should only be used if the code requires its use to achieve the result.

I don’t think you need a dynamic way to pass the object, which is the function of ViewBag. Nor do you need an intermediary where you need to do something extra or better organize the data to be used in view:

<p>@Html.DisplayFor(r => r.StreamUrl) </p>

I would change the query expression to take the redundancy and maybe change the template to deliver an item as you wish (as comments):

var RadioAtivo = db.Radios
    .Where(p => p.Ativo && !p.Mp3)
    .Take(1);
return View(RadioAtivo.ToList()[0]);

Or better yet:

var RadioAtivo = db.Radios
    .Where(p => p.Ativo && !p.Mp3)
    .First();
return View(RadioAtivo.ToList());

As you will receive only one item you will not receive a list, so change:

@model RadioFM.Domain.Domain.Radio

I put in the Github for future reference.

And confirm what I said in the comments, rethink this RadioFM.Domain.Domain.Radio, this doesn’t seem to be necessary.

  • Give an error, saying that Streamurl is not part of System.Collections.Generic.List<Radiofm.domain.Domain.Radio>' and even intellissense does not work

  • Are you sure the guy is this same? RadioFM.Domain.Domain.Radio, when you enter the r. what properties appear?

  • is the path of my Radio class, wouldn’t it? is the List<> the problem?

  • I don’t know, each one makes a way. I found the guy very confused, but it may be because of your need. I hadn’t touched the List. Do you want to present a radio or radio list? If you want a list, you need to add a @foreach in view to go through the list. If you want just one, you need to send an item and not a list. From what I understand only one, and if this is it, it might be interesting to change the controller to deliver an item and not a list. You can still pick up only one on view selecting the first item. Maybe a ViewBag be interesting to organize but not necessary

  • only one item...I put the list in the view pq without it gives the error The model item passed into the Dictionary is of type 'System.Collections.Generic.List`1[Radiofm.domain.Domain.Radio]', but this Dictionary requires a model item of type 'Radiofm.domain.Domain.Radio'.

  • Did what I said above? I edited the answer. I do not know very well the peculiarities (the internal "magic" of ASP.Net MVC but there are some things that do not escape the logic, if you want an item, send an item, there is no error. No longer works with a list. Note that I said that you do not need to solve this with ViewBag or a view model, but you can do this if you prefer. If it’s easier for you, you understand how to do this to solve.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.