繁体   English   中英

如何使用外键在MVC中遍历多个类/表?

[英]How can I move through multiple classes/tables in MVC using foreign keys?

换句话说,如何通过外键遍历类的“层次树”?

下面是树和关联的图片。

这是树和关联的简要图片。

我想分别遍历视图中的表。 显示调查数据和类别数据很容易,因为我只能从查询字符串中引用PK和FK SurveyID。 我不确定在那之后如何从CategoryID到SurveyID获得关联。

这是我的看法

@using (Html.BeginForm("Save", "Surveys"))
{

<div class="form-group">
    @Html.LabelFor(m => m.SurveyId)
    @Html.TextBoxFor(m => m.Description, new { @class = "form-control" })
    @Html.ValidationMessageFor(m => m.Description)
</div>
<div class="form-group">
            @for (int i = 0; i < Model.Categories.Count; i++)
            {
                <ul>@Html.TextBoxFor(m => m.Categories[i].Description, new { @class = "form-control" })</ul>
                @Html.HiddenFor(m => m.Categories[i].CategoryId)
                @*Here is where I attempted to loop the questions based on category*@
                @*@for (int j = 0; j < Model.Categories[i].Questions.Count(); j++)*@
                {
                    @Html.TextBoxFor(m => m.Questions[j].QuestionText)
                }
            }
</div>

    @Html.HiddenFor(m => m.User.Id)
    @Html.HiddenFor(m => m.SurveyId)
    @Html.AntiForgeryToken()
    <button type="submit" class="btn btn-primary">Save</button>
}

我尝试使用for(int j = 0; j <Model.Questions.Count(); j ++)

但是它没有任何结果,我有一种感觉,不管如何,它是行不通的。

我的猜测是问题不在于视图内,而在于控制器如何捕获数据。

public ActionResult Edit(int id)
    {
        var survey = _context.Surveys.SingleOrDefault(c => c.SurveyId == id);
        var categories = new List<Category>();
        categories = _context.Categories.Where(c => c.SurveyId == id).ToList();
        var questions = new List<Question>();
        //questions = _context.Questions.Include()

        //var questions = new List<Question>();
        //questions = _context.Categories.Include(c => c.SurveyId == id).ToList();
        if (survey == null)
            return HttpNotFound();

        var viewModel = new NewSurveyViewModel(survey)
        {
            Questions = questions,
            Categories = categories
        };
        return View("SurveyForm", viewModel);
    }

在这里,我不确定是否应该使用include方法或什么方法,但是我无法考虑如何桥接Category和Survey ID之间的关联,然后再继续使用QuestionID。

我比较近吗?

看起来这可能是数据访问问题,而不是MVC问题。 如果您使用的是实体框架,请参阅“实体框架加载相关实体 ”以确保如何加载对象。

另外,请不要将问题单独加载到viewModel中,因为需要保留层次结构。 您对问题的TextBoxFor调用应利用该功能。

尝试@Html.TextBoxFor(m => m.Categories[i].Questions[j].QuestionText)

JamieSee指出,为了显示数据,必须使用急切加载,如下所示:msdn.microsoft.com/zh-cn/library/jj574232(v=vs.113).aspx

然后从那里开始使用嵌套的foreach循环。

<div class="form-group">
    @foreach (var category in Model.Categories.Where(q => q.SurveyId == Model.SurveyId))
    {
        <ul>@Html.TextBoxFor(m => category.Description, new { @class = "form-control" })</ul>
            @Html.HiddenFor(m => category.CategoryId)

        foreach (var question in Model.Questions.Where(q => q.CategoryId == category.CategoryId))
        {
            <ul>@Html.TextBoxFor(m => question.QuestionText, new { @class = "form-control" })</ul>
                @Html.HiddenFor(m => question.QuestionId)

            foreach (var answer in Model.Answers.Where(a => a.QuestionId == question.QuestionId))
            {
                <ul>@Html.TextBoxFor(m => answer.AnswerText, new { @class = "form-control" })</ul>
                    @Html.HiddenFor(m => answer.AnswerId)
            }
        }
    }
</div>
var db = new DBContext() // => this is your database context

var result = from s in db.Surveys
             select new {
               survey = s,
               categories = from c in db.Categories
                            where c.SurveyID = s.ID
                            select new {
                               category = c,
                               questions = from q in db.Questions
                                           where q.CategoryID = c.ID
                                           select new {
                                               question = q,
                                               answers = from a in db.Answers
                                                         where a.QuestionID = q.ID
                                                         select a
                                            } // close the questions
                            } // close the categories
            };// close the surveys

return result;

如果要在VIEW中使用此查询,则可以使用不带返回结果的查询; 另外,您不需要定义任何数据传输类。

但是,如果您想在控制器内部使用并从任何操作或json结果返回; 您必须在每个选择级别中使用类对象进行数据传输。

例如,第一级DTO类可以是这样;

public class SurveyDTO
{
    public Survey survey{get;set;}
    public List<CategoriesDTO> categories {get;set;}
}

第二级DTO是;

public class CategoriesDTO
{
    public Category category {get;set;}
    public List<QuestionsDTO> questions {get;set;}
}

第三级相同;

public class QuestionsDTO
{
    public Question question {get;set;}
    public List<Answer> answers{get;set;}
}

选择后不要忘记添加DTO名称! 在控制者中; 查询更改如下:

var db = new DBContext() // => this is your database context

var result = (from s in db.Surveys
             select new SurveyDTO(){
               survey = s,
               categories = (from c in db.Categories
                            where c.SurveyID = s.ID
                            select new CategoriesDTO(){
                               category = c,
                               questions = (from q in db.Questions
                                           where q.CategoryID = c.ID
                                           select new QuestionsDTO(){
                                               question = q,
                                               answers = (from a in db.Answers
                                                         where a.QuestionID = q.ID
                                                         select a).ToList()
                                            }).ToList() // close the questions
                            }).ToList() // close the categories
            }).ToList();// close the surveys

return result;

我希望解释清楚并有所帮助。

如果您使用一个查询来获取数据,它将更加快捷

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM