Linq在ASP.NET MVC控制器语法中

时间:2014-01-07 12:44:56

标签: c# asp.net-mvc linq

我是ASP.NET MVC的新手,所以请善待。

我有一个非常简单的数据库,包含三个表格Question,QuestionOptions,Responses。

我在问题中的pk是Id,并在QuestionOptions和Responses中链接到questionId。我在问题中也有一个名为pageId的字段,因此可以在一个页面上显示多个问题。

我在我的控制器中开始使用它;

    // GET: /Questions/ViewQuestion/5
    public ActionResult ViewQuestion(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Question question = db.Questions.Find(id);
        if (question == null)
        {
            return HttpNotFound();
        }
        return View(question);
    }

我的视图完美地返回了一个问题和选项;

@model Template.Models.Question

@{
    ViewBag.Title = "Details";
}
<div>
    <h4>Question #@Model.questionId</h4>
    <hr />
<h1> @Html.DisplayFor(model => model.question1)</h1>
<ul>
    @foreach (var item in Model.QuestionOptions)
    {
        <li>@Html.DisplayFor(modelItem => item.questionOption1)</li>
    }
</ul>

但是现在我正在尝试创建一个视图,该视图将显示具有相同pageID的所有问题 - 并且无处可去。

这是我的新ActionResult;

        public ActionResult ViewQuestion(int? id)
    {
        var pageId = id;
        var question = from q in db.Questions
                       where q.pageId == pageId
                       orderby q.ranking
                       select new { q.questionId,
                       q.questionType, q.question1}
                       ;

        return View(question.ToList());
    }

我的观点;

@model IEnumerable<Template.Models.Question>

@{
    ViewBag.Title = "View question;";
}

<div>
    @foreach (var item in Model) {
    <h4>Question </h4>
    <hr />
    <h1> @Html.DisplayFor(model => item.question1.AsEnumerable())</h1>

    <ul>
        @foreach (var item in Model.QuestionOptions)
        {
            <li>@Html.DisplayFor(modelItem => item.questionOption1)</li>
    }
</ul>
}

但现在它不再将QuestionOptions识别为模型的一部分,即使我评论该部分我仍然得到错误传递到字典中的模型项是类型的 - 但这个字典需要类型System.Collections.Generic.IEnumerable

的模型项

我知道某处我的语法非常错误,但在搜索3天后我不知道在哪里。请帮忙!

3 个答案:

答案 0 :(得分:3)

在您看来,您期待这个模型: @model IEnumerable<Template.Models.Question>

但是您从控制器方法获得的模型不属于此类型,因为您返回的是匿名类型的列表。

你需要改变

var question = from q in db.Questions
               where q.pageId == pageId
               orderby q.ranking
               select new { q.questionId,
                            q.questionType, 
                            q.question1 };

这样的事情:

var question = from q in db.Questions
               where q.pageId == pageId
               orderby q.ranking
               select new Template.Models.Question( )
                          { questionId = q.questionId,
                            questionType = q.questionType, 
                            question1 = q.question1 };

//编辑:

我再看看你的代码。在您的方法ViewQuestion中,您将返回从linq查询中获得的问题。所以我认为你使用的是Model 不是一个特殊的ViewModel。相反,你传递的是Edmx模型。你可以这样做但不是很好的做法。此查询应该适合您:

var questions = from q in db.Questions
                where q.pageId == pageId
                orderby q.ranking
                select q;

但您应该考虑创建自己的Question类,只需在页面上指定所需的值并相应地选择它们。

// EDIT2:

只需考虑一下您在视图中真正需要的内容,并创建一个可以保存此信息的简单类。 (这是一个没有验证规则的超级简单案例等。)

public class QuestionViewModel
{
    public int QuestionId { get; set; }
    public string QuestionType { get; set; }
    public string QuestionText { get; set; }
    // datatypes are only a guess from me, you need to adapt them
}

不要忘记更改视图中的类型

@model IEnumerable<QuestionViewModel>

答案 1 :(得分:2)

您正在创建Anonymous type而非强类型,其中Template.Models.Question是视图所期望的

更好地将其更改为适用于基于模型的视图

select new { q.questionId,
                       q.questionType, q.question1}

select new Template.Models.Question{ q.questionId,
                       q.questionType, q.question1}

答案 2 :(得分:0)

我不确定我应该这样做,但是当你要求查看我的问题类并且它不适合评论时,我在这里发布。如果这是礼仪的话,请原谅我。

namespace Template.Models
{
using System;
using System.Collections.Generic;

public partial class Question
{
    public Question()
    {
        this.QuestionOptions = new HashSet<QuestionOption>();
        this.Responses = new HashSet<Response>();
    }

    public int questionId { get; set; }
    public int eventId { get; set; }
    public int pageId { get; set; }
    public string question1 { get; set; }
    public int questionType { get; set; }
    public Nullable<int> linkedTo { get; set; }
    public Nullable<int> options { get; set; }
    public Nullable<int> ranking { get; set; }

    public virtual ICollection<QuestionOption> QuestionOptions { get; set; }
    public virtual QuestionType QuestionType1 { get; set; }
    public virtual ICollection<Response> Responses { get; set; }
    }
}