ASP/MVC3 Razor Linq

2019-08-04 02:17发布

问题:

I keep getting this error for my project.

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType22[System.String,System.String]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[ETMS.Models.DB.tblParent]'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

==================================================================================

What i want to do is to retrieve the data from the database (one to many) , This is my database table structure

tblparent
- Parent_ID
- Username
- Password
- Firstname
- Lastname

and

tblParentEmail
- ParentEmail_ID
- Email
- Parent_ID

i was made the foreign relation from email to parent, but i could not include with EF while there is another error. i do in this way and caused me this error :

public ActionResult Clientlist()
{
    using (ETMSPeopleEntities db = new ETMSPeopleEntities())
    {
        //var sxc = db.tblParents.Include("tblLocation").Include("tblParentEmails.ParentEmail_ID")
        //    .OrderByDescending(p => p.Status).ToList();
        var members = (from x in db.tblParentEmails
                      join y in db.tblParents
                      on x.Parent_ID equals y.Parent_ID 
                      select new { Email = x.ParentEmail, UserName = y.Username }).AsEnumerable();
        return View(members.ToList());
    }
}

This is my admincontroller

@model IEnumerable<ETMS.Models.DB.tblParent>
@{
    ViewBag.Title = "Clientlist";
}

<h2>Clientlist</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Username
        </th> 
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr> 
        <td>
            @Html.DisplayFor(modelItem => item.Username)
        </td>
         <td>
            @Html.DisplayFor(modelItem => item.Firstname)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Lastname)
        </td>
          <td>
            @Html.DisplayFor(modelItem => item.Location_ID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CreateTime)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Parent_ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.Parent_ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Parent_ID })
        </td>
    </tr>
}

</table>

this is clientlist view

回答1:

You're passing a list of anonymous objects to your view:

select new { Email = x.ParentEmail, UserName = y.Username }

While the view is expecting IEnumerable<ETMS.Models.DB.tblParent>:

@model IEnumerable<ETMS.Models.DB.tblParent>

You should change your selection to:

select y

in order for the code to work.

Update

Here is how you could use a view model pattern. First, create a view model class, so you're not passing an anonymous type to your view. Let's call it AwesomeEmailViewModel, and it looks like you need .Email, .Username and some other properties, so we'll set those up too.

public class AwesomeEmailViewModel
{
    public string Email { get; set; }
    public string Username { get; set; }
    public string FirstName{ get; set; }
    public string LastName { get; set; }
    public int Location_ID{ get; set; }
    public DateTime CreateTime { get; set; }
}

Now, modify your query by using object initialization to populate an instance of AwesomeEmailViewModel

Note: I am guessing which properties belong to which objects (either tblParent or tblParentEmails, so you will need to double-check these

var members = (from x in db.tblParentEmails
               join y in db.tblParents
               on x.Parent_ID equals y.Parent_ID 
               select new AwesomeEmailViewModel()
               { 
                   Email = x.ParentEmail, 
                   UserName = y.Username,
                   FirstName = y.FirstName,
                   LastName = y.LastName,
                   Location_ID = x.Location_ID,
                   CreateTime = y.CreateTime, 
               }).ToList();
               // I don't know if you'll need the `AsEnumerable()` call

return View(members);

Finally, your view has to know what type(s) to expect, so let's modify it to expect a list of our newly created AwesomeEmailViewModel instances.

@model IEnumerable<ETMS.Models.AwesomeEmailViewModel>

Pay close attention, as I guessed at the namespace as well. In any case, this should give you access to the properties you need inside your view. If you need more, you'll need to modify the new view model class we created as well as the query in your controller action.



回答2:

Your view expects tblParent but you are passing it the joined table.

You need to create a ViewModel, join your tables there and change your view to expect the ViewModel rather than tblParent.

Thre are loads of examples. Here's one: ASP.NET MVC ViewModel Pattern

I hope this helps

Davy



回答3:

In the view file, you require a model of type IEnumerable of ETMS.Models.DB.tblParent, and in the controller, you pass in members.ToList(), you have to change either one to make it match.

You can create a viewmodel like this

public Class Client 
{ 
   public string Email {get;set;}
   public string UserName   {get;set;}
}

And return a list of this instead of anonymous type in your controller action, and you will define IEnumerable of Client type in your view.



回答4:

Your returning an anonymous type from your linq query. Your view is expecting a list of type tblParent

Project your linq into the correct type and it should be fine.

At a glance it looks like

select new { Email = x.ParentEmail, UserName = y.Username })

should be

select y


回答5:

That's because you did a "select new" which creates a new anonymous type. The view is expecting tblParent. Anonymous types cannot be cast to a concrete type by the view engine. To fix, either return tblParent from your LINQ query or change your model to "@model dynamic".