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

4

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 in controller and trying to send it to View :

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

return View(RadioAtivo.ToList());

In view , I would like to retrieve, 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 about creating a ViewModel already with the data, but I thought it would sort of duplicate a problem.

What is the simplest solution in this case?

    
asked by anonymous 09.08.2015 / 14:45

2 answers

3

The simplest is the one you are actually doing. Other forms such as 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 do not 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 out redundancy and perhaps would change the template to deliver an item as you wish (as per comments):

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

Or even better:

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

And I confirm what I said in the comments, rethink this RadioFM.Domain.Domain.Radio , this does not seem to be necessary.

    
09.08.2015 / 15:06
5

This does not make sense:

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

return View(RadioAtivo.ToList());

If you want to display only one element on the screen, you do not first need to use Where() with Take() . Not that it does not work, but this returns a list, and what you want is just one element.

You should use First() or Single() (if you are sure that the element exists) or FirstOrDefault() if you do not have this certainty (the first two give an error if the element does not exist):

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

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

return View(RadioAtivo);

View , in turn, does not work with a list, so it does not make sense for you to use this here:

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

@model is for you to tell View which will be placed inside the variable Model (in this spelling, in upper case). The correct one is just the class declaration, as below:

@model RadioFM.Domain.Domain.Radio

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

So, StreamUrl can be displayed like this:

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

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

<p>@Model.StreamUrl</p>
    
10.08.2015 / 02:23