0

I'm doing a project for my college with entity framework where I need to get multiple data from tables without references to each other. The idea would be that in a list basic information appears and when you click the "details" button it shows all the information including those that are not related to this table.

I tried to do this in the controller but sadly, with no success:

public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }


        ProcessArea processArea = db.ProcessArea.Find(id);
        if (processArea == null)
        {
            return HttpNotFound();
        }


        var query = from ap in db.ProcessArea
                    join mg in db.GenericGoal on ap.IdProcessArea equals mg.IdGenericGoal
                    select new ProcessAreaModelView()
                    {
                        InitialsLevelMaturity = mg.Initials,
                        NameLevelMaturity = mg.Name,
                        DescriptionLevelMaturity = mg.Description,
                        Initials = ap.Initials,
                        Name = ap.Name,
                        Description = ap.Description
                    };
        query.ToList();


        return View(query);
    }

I have a model called "Process Area" and as I had to do join I believe I have to have another model since they are different information so I created the "ProcessAreaModelView"

When I click on "details" an error appears:

The template item inserted in the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery'1 [AkaelApp.Models.AreaProcessoModelView]', but this dictionary requires an item of type 'AkaelApp.Models.AreaProcessoModelView'.

What I doing wrong?

3 Answers3

0

The error message says, your view is strongly typed to AreaProcessoModelView, but your code is passing a an IQueryable of AreaProcessoModelView

You need to pass the result of your LINQ query execution to the view , not the query. Since your query expression will return a collection, you need to call First or FirstOrDefault method on the collection to get a single item you need to pass to the view. Your view is strongly typed to a single object, not a collection

Also you are calling Find method on db.ProcessArea , but not actually using it (except to check whether it exist or not). You can add your where clause to your LINQ query.

public ActionResult Details(int? id)
{
    if (id == null)
    {
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }    
     var item = (from ap in db.ProcessArea
                    join mg in db.GenericGoal on ap.IdProcessArea equals mg.IdGenericGoal
                    where ap .Id == id.Value
                    select new AreaProcessoModelView()
                    {
                        InitialsLevelMaturity = mg.Initials,
                        NameLevelMaturity = mg.Name,
                        DescriptionLevelMaturity = mg.Description,
                        Initials = ap.Initials,
                        Name = ap.Name,
                        Description = ap.Description
                    }).FirstOrDefault();

   if(item ==null)
   {
        return HttpNotFound();  // Or a return a view with message "item not found"
   }
   return View(item);
}

This should work assuming your Details view is strongly typed to AreaProcessoModelView class.

Shyju
  • 214,206
  • 104
  • 411
  • 497
0

You need to pass a single instance of AreaProcessoModelView instead of the query.

return View(query.Single());
Dido
  • 520
  • 2
  • 7
  • 21
0

The query returns a list - but you want a single object. You can use query.FirstOrDefault() to get the first match (if more than one match is an error that you want to detect, you can use SingleOrDefault()). You don't need the query.ToList() BTW (you're literally discarding the result).

Dylan Nicholson
  • 1,301
  • 9
  • 23