换句话说,我如何遍历"层次结构树"通过外键我的课程?
下面是树和关联的图片。
我想分别遍历视图中的表格。显示调查数据和类别数据很容易,因为我可以从查询字符串中引用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&lt; 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方法或者什么,但我不能想到如何弥合类别和调查ID之间的关联。然后从那里继续使用QuestionID。
我相对接近吗?
答案 0 :(得分:0)
这看起来可能是数据访问问题而不是MVC问题。如果您正在使用实体框架,Entity Framework Loading Related Entities了解如何确保加载对象。
此外,不要将问题单独加载到viewModel中,因为您需要保留层次结构。你的TextBoxFor问题的调用应该利用它。
尝试@Html.TextBoxFor(m => m.Categories[i].Questions[j].QuestionText)
。
答案 1 :(得分:0)
JamieSee指出,为了显示数据,必须使用第一次急切加载,如下所示msdn.microsoft.com/en-us/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>
答案 2 :(得分:0)
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中使用此查询,可以使用out out return result; 您也不需要定义任何数据传输类。
但是如果你想在控制器内使用并从任何动作或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名称!在contreller;查询会像这样改变;
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;
我希望解释明确并有所帮助。
如果您使用一个查询来获取数据,那将会更加快速