【问题标题】:ASP/MVC3 Razor LinqASP/MVC3 剃须刀 Linq
【发布时间】:2011-08-05 12:43:13
【问题描述】:

我的项目不断收到此错误。

传入字典的模型项是类型 'System.Collections.Generic.List1[<>f__AnonymousType22[System.String,System.String]]', 但是这本词典需要一个类型的模型项 'System.Collections.Generic.IEnumerable`1[ETMS.Models.DB.tblParent]'。

描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。

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

我要做的是从数据库中检索数据(一对多),这是我的数据库表结构

tblparent
- Parent_ID
- Username
- Password
- Firstname
- Lastname

tblParentEmail
- ParentEmail_ID
- Email
- Parent_ID

我是从电子邮件到父母的外来关系,但是当出现另一个错误时,我无法将其包含在 EF 中。我这样做并导致我出现此错误:

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());
    }
}

这是我的管理员控制器

@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>

这是客户列表视图

【问题讨论】:

  • 还有什么错误?您的观点与您的查询有什么关系?您的视图的预期数据和查询的返回日期完全不同。
  • 如果您希望您的视图显示来自tblparenttblParentEmail 的项目,请创建一个具有视图所需的所有属性的 ViewModel 类,并将您的视图绑定到此类(而不是 @ 987654328@) 并在控制器中,而不是使用匿名类型 (select new {...),而是使用视图模型类。

标签: linq asp.net-mvc-3 entity-framework-4.1


【解决方案1】:

你正在向你的视图传递一个匿名对象列表:

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

虽然视图正在等待IEnumerable&lt;ETMS.Models.DB.tblParent&gt;

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

您应该将选择更改为:

select y

为了让代码工作。

更新

这是您可以使用视图模型模式的方法。首先,创建一个视图模型类,这样您就不会将匿名类型传递给您的视图。我们称之为AwesomeEmailViewModel,看起来你需要.Email.Username 和其他一些属性,所以我们也会设置它们。

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; }
}

现在,通过使用对象初始化来修改您的查询以填充 AwesomeEmailViewModel 的实例

注意:我猜测哪些属性属于哪些对象(tblParent 或 tblParentEmails,因此您需要仔细检查这些

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);

最后,您的视图必须知道预期的类型,所以让我们修改它以预期我们新创建的 AwesomeEmailViewModel 实例的列表。

@model IEnumerable<ETMS.Models.AwesomeEmailViewModel>

请密切注意,正如我对命名空间的猜测一样。无论如何,这应该使您可以访问视图中所需的属性。如果您需要更多,则需要修改我们创建的新视图模型类以及控制器操作中的查询。

【讨论】:

  • 改成这个可以查看父信息但是email的值为空
  • @Spencer Lim 是的,你会有一个空的.Email 属性,因为它是tblParentEmails 的属性,而不是tblParent。如果您需要两者的属性,我建议使用视图模型。我会更新我的答案来描述这一点。
  • 终于,我做到了!!!!百万谢谢=D 很遗憾我只能推一次=P
【解决方案2】:

您的视图需要 tblParent,但您正在将连接表传递给它。

您需要创建一个 ViewModel,在那里加入您的表并更改您的视图以期望 ViewModel 而不是 tblParent。

有很多例子。这是一个:ASP.NET MVC ViewModel Pattern

希望对你有帮助

戴维

【讨论】:

    【解决方案3】:

    在视图文件中,您需要一个 ETMS.Models.DB.tblParent 的 IEnumerable 类型的模型,而在控制器中,您传入 members.ToList(),您必须更改其中一个一个让它匹配。

    您可以像这样创建视图模型

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

    并在您的控制器操作中返回此列表而不是匿名类型,您将在视图中定义客户端类型的 IEnumerable。

    【讨论】:

    • 这是不正确的。如果我没看错的话。您是说问题是视图期望 IEnumerable 而他正在传递 List?
    • 没必要,我的意思是,action的返回类型应该和view中定义的一致。
    【解决方案4】:

    您从 linq 查询中返回匿名类型。您的视图需要tblParent

    类型的列表

    将您的 linq 投影到正确的类型,应该没问题。

    乍一看像

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

    应该是

    select y
    

    【讨论】:

    • 将其更改为 select y 没有错误但仍然无法使用 modelitem => item.email 检索电子邮件
    【解决方案5】:

    那是因为你做了一个“select new”,它创建了一个新的匿名类型。该视图期待 tblParent。视图引擎不能将匿名类型转换为具体类型。要解决此问题,请从 LINQ 查询中返回 tblParent 或将模型更改为“@model dynamic”。

    【讨论】:

    • 把它变成动态模型他们不知道从哪里获取数据>.
    • 同意。我自己不会这样做,我应该添加。
    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多