Jaber Kibria
Jaber Kibria

Reputation: 959

Select specific columns using EF in MVC 5

I want to get some specific column values using Entity Framework in MVC 5. But it's showing me error. Here is my code for controller method:

public ActionResult Index()
{
    var systemUsers = db.SystemUsers
                        .Include(s => s.SystemUser1)
                        .Select(s => new {
                                          s.FullName, 
                                          s.Email, 
                                          s.Image, 
                                          s.UpdateDate, 
                                          s.UpdatedBy, 
                                          s.Id
                                 });
    return View(systemUsers.ToList());
}

This is the error message:

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType16[System.String,System.String,System.String,System.Nullable1[System.DateTime],System.Nullable1[System.Int32],System.Int32]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MVC.Models.SystemUser]'.

Again when I'm unable to get single result with specific columns. By default controller method also returning unexpected foreign key data while trying to get using ajax. Here is the code for single result.

[HttpPost]
public ActionResult Details(int? id)
{
    if (id == null)
    {
       return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    SystemUser systemUser = db.SystemUsers.Find(id);
    return Json(systemUser);
}

Here is the result in console

Upvotes: 3

Views: 5353

Answers (2)

Luiso
Luiso

Reputation: 4113

The issue here seems to be that your View is expecting an IEnumerable<SystemUser> as View Model, but instead you are supplying an anonymous type instance. That's why the compiler fails. There are several ways to solve this:

1- Make your View take in a dynamic model: You won't have to worry about the type of the actual instance passed in, however you won't have the niceties of auto-completion or intellisense.

2- Do not project (.Select) your collection and pass the original SystemUser list to the View

3- Create a View Model and make a list of such view models and pass that on to the view:

Controller:

public ActionResult Index()
{
    var systemUsers = db.SystemUsers
                    .Include(s => s.SystemUser1)
                    .Select(s => new SystemUserViewModel 
                            {
                                FullName = s.FullName, 
                                Email = s.Email, 
                                Image = s.Image, 
                                UpdateDate = s.UpdateDate, 
                                UpdatedBy = s.UpdatedBy, 
                                Id = s.Id
                             });
    return View(systemUsers)
}

IMHO the 3rd is the best one. You should of course use the one that suits your needs best. Hope this help

Upvotes: 1

Nkosi
Nkosi

Reputation: 246998

The view requires a strongly typed view model but you are passing an anonymous type

Update the select to return a strongly typed object collection.

public ActionResult Index()
{
    var systemUsers = db.SystemUsers
                        .Include(s => s.SystemUser1)
                        .Select(s => new SystemUser { //<--HERE
                                         FullName = s.FullName, 
                                         Email = s.Email, 
                                         Image = s.Image, 
                                         UpdateDate = s.UpdateDate, 
                                         UpdatedBy = s.UpdatedBy, 
                                         Id = s.Id
                                 });
    return View(systemUsers.ToList());
}

Upvotes: 7

Related Questions