簡體   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