AlexG
AlexG

Reputation: 55

How to get a specific row from database in MVC 4

I have a model called PageModels

public class PageModels
{
    public int id { get; set; }

    public string title { get; set; }

    [DataType(DataType.MultilineText)]
    [AllowHtml]
    public string content { get; set; }

    public int parent { get; set; }

    [DataType(DataType.Date)]
    public DateTime created_at { get; set; }

    [DataType(DataType.Date)]
    public DateTime updated_at { get; set; }

    [DataType(DataType.Date)]
    public DateTime published_at { get; set; }
}

And based on this model I have a controller called PagesController. Here I have a method:

    public ActionResult showPage(string myTitle)
    {
        var query = from a in db.Pages
                    where a.title.Contains(myTitle)
                    select a;

        return View(db.Pages.FirstOrDefault());
    }

I want to be able to get the in the return value the content property of the page that has the title given in myTitle. I haven't been able to find a good way of doing that.

//EDIT

That error that I kept getting was my fault ... between trying to fix my problem and implementing your solution I changed the methods return type to PageModels and that's why it kept throwing me that error. Now it works but the view doesn't show anything. I'll try to fix that myself thanks for all the help.

Upvotes: 1

Views: 13178

Answers (3)

Joseph Morgan
Joseph Morgan

Reputation: 161

You are returning not the selection in the query, but the first record in db.pages. public ActionResult showPage(string myTitle)

 {
        var query = from a in db.Pages
                    where a.title.Contains(myTitle)
                    select a;

        return View(db.Pages.FirstOrDefault());
    }

Instead, you should do this:

public ActionResult showPage(string myTitle)
    {
        var query = (from a in db.Pages
                    where a.title.Contains(myTitle)
                    select a).FirstOrDefault<PageModels>();

        return View(query);
    }

This will send the model containing only the first page that has a title containing your title parameter, which you can use in your markup as needed:

<h1>@Html.Display(@Model.title)</h1>

Note that I have explicitly typed the result as a PageModel, and wrapped the select portion in parentheses. This matters--if you don't tell Linq what type to use, it will give you a generic result that is not an actual instance of the object represented by your data. If you want a type that you have not defined, you can project it into a new type by using

var query=(from a in db.Pages where a.title.Contains(myTitle)
                    select new {a.Title, a.Author});

That will give you an "on the fly" object with a Title and an Author property based on the title and author columns in your data.

Hope this helps--we've all done it.

Joey

Upvotes: 0

Shyju
Shyju

Reputation: 218882

You are getting the result of your filter to the variable query in the first line but you are returning something else (reading all Pages from DB and getting the first item from the collection) to the view.

You need to get the item from the variable query which has the result of your filter.

public ActionResult showPage(string myTitle)
{
    var query = from a in db.Pages
                where a.title.Contains(myTitle)
                select a;

    return View(query.FirstOrDefault());
}

Make sure to do a check for null after FirstOrDefault, otherwise you will run into an exception when there is no records in the collection.

public ActionResult showPage(string myTitle)
{
    var query = from a in db.Pages
                where a.title.Contains(myTitle)
                select a;
    var item=query.FirstOrDefault();
    if(item!=null)
       return View(item);
    else
       return View("NotFound");  //Let's show a view about item not found
}

Upvotes: 2

Santosh Gitay
Santosh Gitay

Reputation: 1

Pass the query to the View

var query = from a in db.Pages
                where a.title.Contains(myTitle)
                select a;
var result = query.FirstOrDefault();
return View (result);

in View use

@HTML.Displyfor(Model.content)

Upvotes: 0

Related Questions